2

データのサブセットを 1 つのテーブル セットから別のデータベース内の同一のテーブル セットにコピーするストアド プロシージャを作成しようとしています。「ソース」データベースは、ストアド プロシージャのパラメーターである必要があります。

私はこれに2日間苦労しましたが、良い解決策があると思いました:

  1. スキーマが同じであることを検証します。
  2. 動的 SQL を使用して、ソース テーブルの一時的な "rmt" シノニムを作成します。
  3. INSERT INTO A SELECT * FROM rmtA WHERE <criteria> を使用してデータをコピーします。
  4. シノニムを削除します。

これはほとんどのテーブルでうまく機能しますが、ID 列を含むテーブルでは、SET IDENTITY_INSERT ON & OFF を強いられるだけでなく、さらに悪いことに SELECT *; を使用することもできません。すべての列を明示的に指定する必要があります。後で列を追加または削除すると、これは悪夢になります。

私はドアから何かを手に入れなければならないので、今のところこの解決策で行きますが、どこかにもっと良い解決策があると思いたいです.

ヘルプ?

4

1 に答える 1

1

ストアド プロシージャで動的 SQL を使用しているように聞こえるので、SELECT 句で列のリストを動的に作成する準備が整いました。

sys.columns から選択して列のリストを取得し、テーブルに ID 列があるかどうかを確認できます。列のリストを作成するために必要な情報を示すクエリを次に示します。

SELECT c.name, is_identity
FORM sys.columns c
WHERE object_id = object_id('MyTable')

つまり、is_identity少なくとも 1 つの列で が 1 の場合、. を含める必要がありますSET IDENTITY_INSERTis_identityまた、 = 1である SELECT 句から列を除外します。

また、このアプローチは、テーブルに追加する新しい列に適応します。

これが例です

DECLARE @TableName varchar(128) = 'MyTableName'
DECLARE @ColumnName varchar(128)
DECLARE @IsIdentity bit
DECLARE @TableHasIdentity bit = 0
DECLARE @sql varchar(2000) = 'SELECT '

-- create cursor to step through list of columns
DECLARE MyCurs CURSOR FOR
SELECT c.name, is_identity
FROM sys.columns c
WHERE object_id = object_id(@TableName)
ORDER BY column_id

-- open cursor and get first row
OPEN MyCurs
FETCH NEXT FROM MyCurs INTO @ColumnName, @IsIdentity

-- process each column in the table
WHILE @@FETCH_STATUS = 0
  BEGIN
    IF @IsIdentity = 0
-- add column to the SELECT clause
        SET @sql = @sql + @ColumnName + ', '
    ELSE
-- indicate that table has identity column  
        SET @TableHasIdentity = 1

-- get next column
    FETCH NEXT FROM MyCurs INTO @ColumnName, @IsIdentity
  END

-- cursor cleanup
CLOSE MyCurs
DEALLOCATE MyCurs

-- add FROM clause
SET @sql = LEFT(@sql, LEN(@sql)-1) + CHAR(13) + CHAR(10) + 'FROM ' + @TableName

-- add SET IDENTITY if necessary
IF @TableHasIdentity = 1
    SET @sql = 'SET IDENTITY_INSERT ' + @TableName + ' ON' + CHAR(13) + CHAR (10)
                + @sql + CHAR(13) + CHAR (10)
                + 'SET IDENTITY_INSERT ' + @TableName + ' OFF'

PRINT @sql
于 2010-08-04T04:10:27.080 に答える