[英]T-SQL: How to find if a column exists in a list of tables
My goal is to get a list of tables from a stored procedure and then return the name of those tables along with their row count and if a ModifiedDate
column exists in each table.我的目标是从存储过程中获取表列表,然后返回这些表的名称及其行数,以及每个表中是否存在
ModifiedDate
列。
So far it almost works but this current code gives me back a few tables where it says ModifiedDate
both exists and doesn't exist.到目前为止,它几乎可以工作,但是当前的代码给了我一些表,其中显示
ModifiedDate
既存在又不存在。 I'm guessing the problem lies in that last select statement.我猜问题在于最后一个 select 语句。
-- Create temporary table
CREATE TABLE #TempTable
(
[object_name] NVARCHAR(255) ,
[object_id] NVARCHAR(255),
[row_count] INT
)
-- Insert table names, object id and row count into temp table
INSERT INTO #TempTable
SELECT DISTINCT
[object_name] = SCHEMA_NAME(o.[schema_id]) + '.' + o.name ,
o.object_id,
ddps.row_count
FROM sys.dm_sql_referenced_entities('dbo.spMyStoredProcedure',
'OBJECT') d
JOIN sys.objects o ON d.referenced_id = o.[object_id]
INNER JOIN sys.indexes AS i ON i.object_id = o.object_id
INNER JOIN sys.dm_db_partition_stats AS ddps ON i.object_id = ddps.object_id
AND i.index_id = ddps.index_id
WHERE o.[type] IN ( 'U', 'V' )
AND i.index_id < 2
AND o.is_ms_shipped = 0;
-- Join temp table to query that searches for a ModifiedDate column
SELECT DISTINCT t2.[object_name] AS 'TableName' ,
t2.[row_count] AS 'RowCount' ,
CASE
WHEN t1.name ='modifiedDate' THEN 'Yes'
WHEN t1.name <> 'modifiedDate' THEN 'No'
END AS 'ModifiedDateExists'
FROM sys.columns AS t1
RIGHT JOIN #TempTable AS t2 ON t1.object_id = t2.object_id;
-- Delete temp table
IF ( OBJECT_ID('mydbhere..#TempTable') IS NOT NULL )
BEGIN
DROP TABLE #TempTable
END;
The problem is the sys.columns
will contain multiple records for 1 object (table) (one for each column).问题是
sys.columns
将包含 1 个对象(表)的多个记录(每列一个)。 You need a 1-1 relationship there.您需要在那里建立 1-1 关系。 The distinct you're using is hiding the fact that you'd have a lot more rows (1 for each field in fact).
您正在使用的不同的是隐藏的事实,你有更多的行(1其实每个字段)。
So you need to ensure only 1 record is returned from the join between sys.columns
and #TempTable
.因此,您需要确保从
sys.columns
和#TempTable
之间的连接中只返回 1 条记录。 This can be done by only searching for modifiedDate
and allowing the existing of a NULL on your right join to mean that it doesn't exit.这可以通过仅搜索
modifiedDate
并允许右连接上存在 NULL 来表示它不会退出来完成。
SELECT t2.[object_name] AS 'TableName'
, t2.[row_count] AS 'RowCount'
, case when t1.name is not null then 'YES' else 'No' as 'ModifiedDateExists'
FROM sys.columns AS t1
RIGHT JOIN #TempTable AS t2
ON t1.object_id = t2.object_id
and t1.name ='modifiedDate'
Since SQL server will prevent the same named object (column/field) from being in a table, simply limit to just that column;由于 SQL Server 会阻止同名对象(列/字段)出现在表中,因此只需限制为该列即可; all other records would result in a Null, and then in our case statement we can say yes or no.
所有其他记录都将导致 Null,然后在我们的 case 语句中我们可以说是或否。
All the tables in #tempTable
will be returned but only 1 column. #tempTable
所有表#tempTable
将被返回,但只有 1 列。
A general rule of thumb is to avoid Distinct unless you really mean it as it generally is just hiding a problem on a join, limit or something.一般的经验法则是避免 Distinct ,除非您真的是认真的,因为它通常只是隐藏连接、限制或其他方面的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.