从不同数据库中的 sys.columns 中提取数据

web*_*ad3 3 sql-server

我在服务器上的一个实例上运行以下内容:

SELECT c.*
FROM sys.columns c
WHERE c.object_id = OBJECT_ID(@tablename);
Run Code Online (Sandbox Code Playgroud)

一切都很好。

我想运行相同的语句,但将其指向服务器上的另一个数据库。

数据库名.dbo.表名

我已经尝试了以下(和其他变体),但它不起作用。

SELECT c.*
FROM sys.columns c
WHERE c.object_id = OBJECT_ID('databaseName.dbo.tablename');
Run Code Online (Sandbox Code Playgroud)

有没有办法从另一个数据库获取一个数据库的列信息?

代码:

SELECT @SQL = @SQL + 'INSERT INTO myTable 
  (ColumnName,ColumnValue,SID,SName,RID,RName)
  VALUES (''' + QUOTENAME(c.name) + ''',NULL,0,NULL,0,NULL);'
            FROM sys.columns c
            WHERE c.object_id = OBJECT_ID(@tablename);

EXEC(@SQL);
Run Code Online (Sandbox Code Playgroud)

有没有办法动态地做到这一点?如果我有一个@DBName我正在传递的参数。

tpe*_*pet 6

在 sys.columns 前面添加您要查询的数据库。

SELECT c.*
FROM <other database name>.sys.columns c
WHERE c.object_id = OBJECT_ID(@tablename);
Run Code Online (Sandbox Code Playgroud)


Aar*_*and 5

您可以这样动态地执行此操作:

-- parameters to the procedure:
DECLARE @dbname sysname = N'master', @tablename sysname = N'spt_values';


DECLARE @sql nvarchar(max),
  @exec nvarchar(max) = QUOTENAME(@dbname) + N'.sys.sp_executesql';

SET @sql = N'--insert SourceDatabase.dbo.myTable(...)
  SELECT QUOTENAME(c.name),NULL,0,NULL,0,NULL 
  FROM sys.columns AS c -- these will be in @dbname
  INNER JOIN sys.all_objects AS t
  ON c.[object_id] = t.[object_id]
  WHERE t.[schema_id] = 1    -- seems you assume everything will be dbo.
  AND t.name = @tablename;'; -- don't need to protect table name

-- magic sauce: this turns into EXEC dbname.sys.sp_executesql @sql...:
EXEC @exec @sql, N'@tablename sysname', @tablename;
Run Code Online (Sandbox Code Playgroud)

@dbname恕我直言,这比连接到语句中要安全得多。

如果您需要支持更多dbo(同样,我根据问题中的所有查询做出了假设),那么很容易添加:

-- parameters:
DECLARE @dbname     sysname = N'master', 
        @schemaname sysname = N'dbo', 
        @tablename  sysname = N'spt_values';


DECLARE @sql nvarchar(max),
  @exec nvarchar(max) = QUOTENAME(@dbname) + N'.sys.sp_executesql';

SET @sql = N'--insert SourceDatabase.dbo.myTable(...)
  SELECT QUOTENAME(c.name),NULL,0,NULL,0,NULL 
  FROM sys.columns AS c -- these will be in @dbname
  INNER JOIN sys.all_objects AS t
  ON c.[object_id] = t.[object_id]
  INNER JOIN sys.schemas AS s
  ON t.[schema_id] = s.[schema_id]
  WHERE s.name = @schemaname
  AND t.name = @tablename;';

-- magic sauce: this turns into EXEC dbname.sys.sp_executesql @sql...:
EXEC @exec @sql, N'@tablename sysname, @schemaname sysname', @tablename, @schemaname;
Run Code Online (Sandbox Code Playgroud)