2

数百のテーブルを含むデモデータベースがあります。各テーブルには通常、smalldatetimeデータ型であるtstampという名前のフィールドが少なくとも1つあります。一部のテーブルには他の日付フィールドもあります。多くのテーブルには、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!

================================================== ========================================トリガーの問題を省略して、次のようなスクリプトを作成します。作品:

DECLARE @numDaysToAdd int

SET @numDaysToAdd = 1

@numDaysToAdd>0の場合

始める

DECLARE @tablename varchar(100)

DECLARE @currtable varchar(100)

DECLARE @currcolumn varchar(100)

DECLARE @columnname varchar(100)

DECLARE @strSQL nvarchar(4000)

tnames_cursorCURSORを宣言します

にとって

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 ='smalldatetime' OR c.DATA_TYPE ='datetime')AND t.TABLE_TYPE <>'VIEW'

t.TABLE_NAME、c.COLUMN_NAMEDESCによる注文

OPEN tnames_cursor

FETCH NEXT FROM tnames_cursor INTO @ tablename、@ columnname

SET @currcolumn = @columnname

SET @currtable = @tablename

SET @strSQL = N'UPDATE' + @tablename + CHAR(13)+ CHAR(10)+'SET' + @columnname +'= DATEADD(day、' + CONVERT(varchar(10)、@ numDaysToAdd)+'、 '+ @columnname +') '

WHILE(@@ FETCH_STATUS = 0)

始める

IF(@currtable = @tablename)

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

FETCH NEXT FROM tnames_cursor INTO @ tablename、@ columnname

終わり

--最後のステートメントEXECsp_executesql@strSQLを実行します

tnames_cursorを閉じる

tnames_cursorの割り当てを解除します

終わり

4

3 に答える 3

1

あなたの理解は正しいです。あなたが見逃している部分は次のように聞こえます:

  1. メタデータを見つける方法(どのテーブルとどの列があるか)
  2. テーブルをウォークオーバーするSQLを構築する方法。

#1については、システムビューINFORMATION_SCHEMA.TABLESINFORMATION_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

于 2009-07-02T20:03:57.883 に答える
0

同意します。もう1つのオプションは、システムテーブルを使用して、200個すべてのテーブルのSQLを生成することです。その後、sp_execsqlを使用してexecを実行できます。実行は変更されませんが、入力する手間が省けます。これは常に重要です:)

于 2009-07-02T20:04:47.447 に答える
0

次のクエリは、タイプ'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はデータ型--smallDateTimeのsystem_type_idです。sys.typesテーブルから確認できます。

カーソルを使用すると、結果セットを反復処理して各テーブルを取得し、そのテーブルのトリガーを無効にできます。トリガーの無効化/有効化については、これを確認してくださいhttp://msdn.microsoft.com/en-us/library/ms189748.aspx

次に、各テーブルに関連する結果セットの各列を更新してから、トリガーを有効にします。

乾杯

于 2009-07-02T20:20:50.830 に答える