SQL Server编程-按给定天数更新所有日期
-
21-08-2019 - |
题
我有一个演示数据库,其中有几百个表。每个表通常至少有一个名为 tstamp 的字段,它是一种小日期时间数据类型。有些表还有其他日期字段。许多表上还有 1 个或多个触发器。
我编写了一个脚本(困难的方法 - 见下文),将每个表中的日期字段增加给定的天数。其想法是通过将所有日期更新相同的天数来使数据显得更加“最新”。
我确信有一种更简单的方法可以通过循环系统表来识别数据库中的每个用户表,禁用其上的所有触发器,通过添加天数来修改每个smalldatetime字段,重新启用触发器并移动到下一张桌子。我只是不知道如何编写这样的 T-SQL。
有接受者吗?
谢谢。乔
示例脚本:
DECLARE @numDaysToAdd int
SET @numDaysToAdd = 100
ALTER TABLE someTableDISABLE TRIGGER someTrigger
UPDATE someTable
SET tstamp = DATEADD(day, @numDaysToAdd, tstamp)
-- update any other smalldatetime field in the table too.
ALTER TABLE someTable ENABLE TRIGGER someTrigger
-- same pattern for 200 more tables!
=============================================== =================================作品:
声明 @numDaysToAdd int
设置@numDaysToAdd = 1
如果@numDaysToAdd > 0
开始
声明 @tablename varchar(100)
声明 @currtable varchar(100)
声明 @currcolumn varchar(100)
声明@columnname varchar(100)
声明 @strSQL nvarchar(4000)
声明 tnames_cursor 游标
为了
选择 t.TABLE_NAME、c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c join INFORMATION_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME
WHERE (c.DATA_TYPE = 'smalldatetime' OR c.DATA_TYPE = 'datetime') AND t.TABLE_TYPE<>'VIEW'
ORDER BY t.TABLE_NAME, c.COLUMN_NAME DESC
打开tnames_cursor
从 tnames_cursor 获取下一个 INTO @tablename, @columnname
SET @currcolumn = @columnname
SET @currtable = @表名
SET @strSQL = N'UPDATE ' + @tablename + CHAR(13)+CHAR(10) + 'SET' + @columnname + ' = DATEADD(day, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @列名 + ')'
同时(@@FETCH_STATUS = 0)
开始
IF (@currtable = @表名)
BEGIN
IF @currcolumn <> @columnname
SET @strSQL = @strSQL + N',' + CHAR(13)+CHAR(10) + @columnname + ' = DATEADD(day, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @columnname + ')'
END
别的
BEGIN
SET @currtable = @tablename
SET @currcolumn = @columnname
EXEC sp_executesql @strSQL
SET @strSQL = N'UPDATE ' + @tablename + CHAR(13)+CHAR(10) + 'SET ' + @columnname + ' = DATEADD(day, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @columnname + ')'
END
从 tnames_cursor 获取下一个 INTO @tablename, @columnname
结尾
- 运行最终语句exec sp_executesql @strsql
关闭 tnames_cursor
解除分配 tnames_cursor
结尾
解决方案
你的理解是正确的。听起来您缺少的部分是:
- 如何找到元数据(您拥有哪些表,哪些列)
- 如何建立SQL以在桌子上行走。
对于#1,请参阅系统视图 INFORMATION_SCHEMA.TABLES
和 INFORMATION_SCHEMA.COLUMNS
:
-- add your own additional criteria
select t.TABLE_NAME, c.COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS c
join INFORMATION_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME
WHERE c.DATA_TYPE = 'datetime'
对于#2,您可以将 SQL 语句构建为字符串,遍历您感兴趣的表,然后使用 sp_executesql
.
其他提示
我同意。另一种选择是使用系统表生成所有200代表的SQL。然后,您可以使用sp_execsql到EXEC。不会改变执行,但会为您节省打字,这始终是重要的:)
在下面的查询会给你用户表和它们的列是哪个类型的“SMALLDATETIME”的列表。
SELECT sys.columns.name as tableName, sys.tables.name as columnName from sys.columns,sys.tables
where sys.columns.object_id=sys.tables.object_id and sys.columns.system_type_id=58 order by tableName
这里58 system_type_id数据类型 - SMALLDATETIME。可以从表sys.types验证它。
使用光标可以是你可以遍历结果集来获得每个表,然后禁用该表上的触发器。检查这个触发禁用/启用 http://msdn.microsoft.com/en -us /库/ ms189748.aspx
然后继续前进,更新结果集中属于每个表中的每一列中,随后通过使触发器。
欢呼声