在 SQL 服务器中,如何从子查询中标识的 table 列名称中检索数据值?
In SQL Server, how do I retrieve data values from table column names identified in a sub-query?
我正在使用以下 SQL 列出我架构中的所有 table 和列名称,用于 tables 包含其名称包含字符串 "code" 的列,使用以下 SQL 服务器查询:
SELECT
a.table_name, a.column_name from (SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM
sys.tables AS t
INNER JOIN
sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE
c.name LIKE '%code%') a
结果:
Table Name Column Name
---------- -----------
Tab_1_name a_code
Tab_2_name another_code
Tab_3_name yet_another_code
and so on...
我现在想使用包装器查询 a_code 和 another_code 列中的实际数据,但看不到如何获取实际数据(例如,如果单独为选项卡 1 执行操作) , 我会
SELECT a_code FROM Tab_1
获得
a_code
------
value 1
value 2
value 3
但无法弄清楚或在任何地方找到如何对外部查询进行编码以环绕上述内容,这样我会得到类似以下内容的内容:
Tab1_name a_code
--------- ------
tab_name 1 value 1
tab_name 1 value 2
tab_name 2 value 1
tab_name 2 value 2
tab_name 3 value 1
tab_name 3 value 2 ... etc.
即我的 schema/DB 中所有 table 列中所有数据值的格式化列表,其名称包含单词 "code"?
没有动态SQL,无论如何也做不到。
这里有一些可以帮助您入门的内容。
DECLARE @SearchTerm NVARCHAR(50)
SELECT @SearchTerm = '%id%'
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
INTO #temp
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE @SearchTerm
ORDER BY t.name
DECLARE @Query NVARCHAR(MAX),
@tableName NVARCHAR(250),
@schemaName NVARCHAR(10),
@columnName NVARCHAR(250)
SELECT @Query = 'SELECT SchemaName = '''',
TableName = '''',
ColumnName = '''',
Value = CONVERT(NVARCHAR(MAX), '''')
WHERE 0 = 1'
WHILE(EXISTS(SELECT TOP 1 1 FROM #temp))
BEGIN
SELECT TOP 1 @tableName = table_name,
@schemaName = [schema_name],
@columnName = column_name
FROM #temp
SELECT @Query = @Query + ' UNION ALL SELECT SchemaName = ''' + @schemaName + ''',
TableName = ''' + @tableName + ''',
ColumnName = ''' + @columnName + ''',
Value = CASE WHEN ' + @columnName + ' IS NULL THEN ''NULL'' ELSE CONVERT(NVARCHAR(MAX), ' + @columnName + ') END
FROM ' + @tableName
DELETE #temp
WHERE table_name = @tableName
AND @schemaName = [schema_name]
AND @columnName = column_name
END
PRINT @Query
EXEC sp_executesql @Query
DROP TABLE #temp
以上查询return以下信息:
SchemaName TableName ColumnName 值
请注意,通过 returning 所有匹配列的值,您很可能会遇到转换问题和 null 转换问题。在上面的查询中,处理了基本情况,但是对于某些复杂的 SQL 列类型,转换为 'NVARCHAR' 可能仍然会失败。
use master
GO
declare
@sql varchar(max) = '',
@colpattern varchar(100) = '%name%'
;with cteSchema as
(
select
object_schema_name(t.object_id) + '.' + quotename(t.name) as tabname,
quotename(c.name) as colname
from sys.tables t
inner join sys.columns c on c.object_id = t.object_id
where c.name like @colpattern
)
select @sql =
(
select
cast('
select cast(t.' as varchar(max)) + t.colname + ' as varchar(1000)) as [value] '
+ ', cast(''' + t.tabname + '.' + t.colname + ''' as nvarchar(2000)) as [source] '
+ ' from ' + t.tabname + ' t
union all '
from cteSchema t
order by t.tabname, t.colname
for xml path(''), type
).value('.', 'varchar(max)')
+ '
select null, null where 1=0
order by [source], [value]'
print @sql
exec (@sql)
GO
我正在使用以下 SQL 列出我架构中的所有 table 和列名称,用于 tables 包含其名称包含字符串 "code" 的列,使用以下 SQL 服务器查询:
SELECT
a.table_name, a.column_name from (SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM
sys.tables AS t
INNER JOIN
sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE
c.name LIKE '%code%') a
结果:
Table Name Column Name
---------- -----------
Tab_1_name a_code
Tab_2_name another_code
Tab_3_name yet_another_code
and so on...
我现在想使用包装器查询 a_code 和 another_code 列中的实际数据,但看不到如何获取实际数据(例如,如果单独为选项卡 1 执行操作) , 我会
SELECT a_code FROM Tab_1
获得
a_code
------
value 1
value 2
value 3
但无法弄清楚或在任何地方找到如何对外部查询进行编码以环绕上述内容,这样我会得到类似以下内容的内容:
Tab1_name a_code
--------- ------
tab_name 1 value 1
tab_name 1 value 2
tab_name 2 value 1
tab_name 2 value 2
tab_name 3 value 1
tab_name 3 value 2 ... etc.
即我的 schema/DB 中所有 table 列中所有数据值的格式化列表,其名称包含单词 "code"?
没有动态SQL,无论如何也做不到。
这里有一些可以帮助您入门的内容。
DECLARE @SearchTerm NVARCHAR(50)
SELECT @SearchTerm = '%id%'
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
INTO #temp
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE @SearchTerm
ORDER BY t.name
DECLARE @Query NVARCHAR(MAX),
@tableName NVARCHAR(250),
@schemaName NVARCHAR(10),
@columnName NVARCHAR(250)
SELECT @Query = 'SELECT SchemaName = '''',
TableName = '''',
ColumnName = '''',
Value = CONVERT(NVARCHAR(MAX), '''')
WHERE 0 = 1'
WHILE(EXISTS(SELECT TOP 1 1 FROM #temp))
BEGIN
SELECT TOP 1 @tableName = table_name,
@schemaName = [schema_name],
@columnName = column_name
FROM #temp
SELECT @Query = @Query + ' UNION ALL SELECT SchemaName = ''' + @schemaName + ''',
TableName = ''' + @tableName + ''',
ColumnName = ''' + @columnName + ''',
Value = CASE WHEN ' + @columnName + ' IS NULL THEN ''NULL'' ELSE CONVERT(NVARCHAR(MAX), ' + @columnName + ') END
FROM ' + @tableName
DELETE #temp
WHERE table_name = @tableName
AND @schemaName = [schema_name]
AND @columnName = column_name
END
PRINT @Query
EXEC sp_executesql @Query
DROP TABLE #temp
以上查询return以下信息: SchemaName TableName ColumnName 值
请注意,通过 returning 所有匹配列的值,您很可能会遇到转换问题和 null 转换问题。在上面的查询中,处理了基本情况,但是对于某些复杂的 SQL 列类型,转换为 'NVARCHAR' 可能仍然会失败。
use master
GO
declare
@sql varchar(max) = '',
@colpattern varchar(100) = '%name%'
;with cteSchema as
(
select
object_schema_name(t.object_id) + '.' + quotename(t.name) as tabname,
quotename(c.name) as colname
from sys.tables t
inner join sys.columns c on c.object_id = t.object_id
where c.name like @colpattern
)
select @sql =
(
select
cast('
select cast(t.' as varchar(max)) + t.colname + ' as varchar(1000)) as [value] '
+ ', cast(''' + t.tabname + '.' + t.colname + ''' as nvarchar(2000)) as [source] '
+ ' from ' + t.tabname + ' t
union all '
from cteSchema t
order by t.tabname, t.colname
for xml path(''), type
).value('.', 'varchar(max)')
+ '
select null, null where 1=0
order by [source], [value]'
print @sql
exec (@sql)
GO