例如,我在数据库中有2个表。 例如: 表T:
declare @t table (name varchar(20),DOB date)
Insert into @t (name,DOB) values ('Mohan','2001-07-19')
Insert into @t (name,DOB) values ('Minu','1998-06-19')
表:TT
declare @tt table (name varchar(20),DOB date)
Insert into @tt (name,DOB) values ('Raju','2010-07-19')
Insert into @tt (name,DOB) values ('Rani','2001-06-19')
现在我有一个查询,可以基于日期类型过滤器获取多个表的表名和列名。
SELECT C.TABLE_SCHEMA, c.TABLE_NAME,c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c
JOIN sys.objects o ON o.name = c.TABLE_NAME
WHERE o.type = 'U' AND C.DATA_TYPE = 'Datetime'
输出:
T_Schema T_name T_column
dbo T DOB
dbo TT DOB
但是如何获得两个表的最大日期,如下所示:
T_Schema T_name T_column Max_dt
dbo T DOB 2001-07-19
dbo TT DOB 2010-07-19
建议我实现这一目标的最佳方法。
答案 0 :(得分:6)
这是不使用光标的另一个选项。我怀疑从性能的角度来看会不会更好,因为您仍然需要为每一行使用子查询。但是我真的很讨厌游标。我还使用了系统表而不是信息模式视图,因为有时它们可能有些奇怪。 https://sqlblog.org/2011/11/03/the-case-against-information_schema-views
declare @SQL nvarchar(max) = N''
select @SQL = @SQL +
N'select SCHEMA_NAME = ''' + QUOTENAME(s.name) + ''', TABLE_NAME = '''
+ QUOTENAME(o.name) + ''', COLUMN_NAME = '''
+ QUOTENAME(c.name) + ''', MaxDate = '
+ '(select MAX(' + QUOTENAME(c.name) + ') from ' + QUOTENAME(s.name) + '.' + QUOTENAME(o.name) + ') UNION ALL '
from sys.columns c
join sys.systypes st on st.type = c.system_type_id
join sys.objects o on o.object_id = c.object_id and o.type = 'U'
join sys.schemas s on s.schema_id = o.schema_id
where st.name = 'datetime'
order by s.name
, o.name
, c.name
set @SQL = left(@SQL, len(@SQL) - 10) --removes final UNION ALL
select @SQL
--uncomment below when you are satisfied the dynamic sql is correct
--exec sp_executesql @SQL
答案 1 :(得分:3)
这里有一些动态SQL,可以通过游标执行所需的操作。
如果您有很多表,请谨慎使用,或者先在测试中运行它。一般而言,游标的表现不佳。您可以针对系统数据库(例如master)运行此数据库,该数据库具有较少的值以查看其工作方式。
create table #MaxDate (tname varchar(256), cname varchar(256), mdate datetime)
declare cur cursor local fast_forward
for
SELECT C.TABLE_SCHEMA, c.TABLE_NAME,c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c
JOIN sys.objects o ON o.name = c.TABLE_NAME
WHERE o.type = 'U' AND C.DATA_TYPE = 'Datetime'
declare @schema varchar(64), @table varchar(256), @column varchar(256)
declare @sql varchar(max)
open cur
fetch next from cur into @schema, @table, @column
while @@FETCH_STATUS = 0
begin
set @sql = 'select ''' + @table + '''' + ',''' + '' + @column + '''' + ',' + 'max(' + @column + ') from ' + @schema + '.' + @table
print @sql
insert into #MaxDate
exec (@sql)
fetch next from cur into @schema, @table, @column
end
close cur
deallocate cur
select * from #MaxDate
drop table #MaxDate
答案 2 :(得分:3)
以下是使用游标,动态SQL和临时表的答案:
openssl genrsa -out cluster-admin-key.pem 4096
openssl req -new -key cluster-admin-key.pem -out cluster-admin.csr -subj "/CN=cluster-admin/O=system:masters"
openssl x509 -req -in cluster-admin.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cluster-admin.pem -days 3650
答案 3 :(得分:2)
SQL为您构建SQL
DECLARE @SQL as nvarchar(max) ='';
select @SQL = @SQL + 'SELECT ' + Column_Name + ' adate, ''' + Column_Name + ''' colname, ''' + Table_name + ''' tabname FROM ' + Table_name + ' UNION ' FROM INFORMATION_SCHEMA.COLUMNS where data_type like '%date%'
select @SQL = 'SELECT TOP 100 * FROM (' + LEFT(@SQL, LEN(@SQL) -6) + ') IQ WHERE IQ.adate IS NOT null ORDER BY IQ.adate DESC';
--cut n paste the sql below, see what it does for you
select @SQL
mark II-为您执行sql,并在其中排序带有空格的名称
DECLARE @SQL as nvarchar(max) ='';
select @SQL = @SQL + 'SELECT [' + Column_Name + '] adate, ''' + Column_Name + ''' colname, ''' + Table_name + ''' tabname FROM [' + Table_name + '] UNION ' FROM INFORMATION_SCHEMA.COLUMNS where data_type like '%date%'
select @SQL = 'SELECT TOP 100 * FROM (' + LEFT(@SQL, LEN(@SQL) -6) + ') IQ WHERE IQ.adate IS NOT null ORDER BY IQ.adate DESC';
select @SQL;
EXEC sp_executesql @sql;