3

注: SQL Server 2008 R2 で実行しています...

クエリが 4000 文字を超える場合に動的 SQL を実行する方法について、このサイトや他のサイトで数十の投稿を読むのに時間をかけました。私は提案された十数以上の解決策を試しました。コンセンサスは、クエリを 4000 文字の変数に分割してから実行することです。

EXEC (@SQLQuery1 + @SQLQuery2)

これは私にはうまくいきません - クエリは @SQLQuery1 の最後で切り捨てられます。

さて、私は人々が REPLICATE を使用して一連のスペースなどを使用して長いクエリを「強制」する方法のサンプルを見てきましたが、これは実際のクエリですが、それよりも少し洗練されています。

「Company_A_ItemView」という名前の SQL ビューがあります。

「Company_B_ItemView」「Company_C_ItemView」など、異なる名前でまったく同じビューを作成したい10社があります。

助けを提供する場合は、複数のビューがある理由を尋ねないでください。このようにする必要があることを受け入れてください。

各会社には独自のテーブル セットがあり、CREATE VIEW ステートメントは複数のテーブルを名前で参照します。簡単なサンプルを次に示しますが、クエリの合計の長さは約 6000 文字です。

CREATE view [dbo].[Company_A_ItemView] as  
select  
WE.[Item No_],  
WE.[Location Code],   
    LOC.[Bin Number],  
[..more fields, etc.]  
from  
[Company_A_Warehouse_Entry] WE  
left join  
[Company_A_Location] LOC  

...あなたはアイデアを得る

だから、私が現在やっていることは次のとおりです。

を。CREATE VIEW ステートメントの内容を 2 つの宣言された変数にプルします。

Set @SQLQuery1 = (select text 
                  from syscomments 
                  where ID = 1382894081 and colid = 1)  
Set @SQLQuery2 = (select 
                  from syscomments 
                  where ID = 1382894081 and colid = 2)

これは、SQL が長い定義を保存する方法であることに注意してください。ビューを作成すると、テキストが複数の syscomments レコードに保存されます。私の場合、ビューは最初の syscomment レコードに 3591 文字のテキスト チャンクに分割され、残りのテキストは 2 番目のレコードにあります。SQL が syscomment フィールドで 4000 文字すべてを使用しない理由がわかりません。そして、ステートメントは単語の途中で壊れています。

私のすべての例で、すべての @SQLQueryxxx 変数が varchar(max) として宣言されていることに注意してください。また、同じ結果で nvarchar(max) および varchar(8000) および nvarchar(8000) として宣言しようとしました。

b. 次に、「Company_A」の「検索と置換」を実行し、「Company_B」に置き換えます。以下のコードでは、変数「@CompanyID」が最初に「Company_B」に設定されています。

SET @SQLQueryNew1 = @SQLQuery1   
SET @SQLQueryNew1 = REPLACE(@SQLQueryNew1, 'Company_A', @CompanyID)  
SET @SQLQueryNew2  = @SQLQuery2   
SET @SQLQueryNew2 = REPLACE(@SQLQueryNew2, 'Company_A',@CompanyID)

c. 次に試します:

EXEC (@SQLQueryNew1 + @SQLQueryNew2)

返されたメッセージは、@SQLQueryNew1 の最後で切り捨てられたステートメントを実行しようとしていることを示しています。たとえば、クエリのテキストの 80% (約) です。

最終結果を新しい varchar(max) と nvarchar(max) に CAST しようとしました - 運が悪い 元のクエリを新しい varchar(max) と nvarchar(max) に CAST しようとしました - 運が悪い

元の CREATE VIEW ステートメントを取得した結果を確認しましたが、問題ありません。

次のような、元の CREATE VIEW ステートメントを取得するさまざまな方法を試しました。

Set @SQLQuery1 = (select VIEW_DEFINITION) 
                  FROM [MY_DATABASE].[INFORMATION_SCHEMA].[VIEWS] 
                  where TABLE_NAME = 'Company_A_ItemView')`

これは、CREATE VIEW の最初の 4000 文字のみを返します。

Set @SQLQuery1 = (SELECT (OBJECT_DEFINITION(@ObjectID))

私がする場合

SELECT LEN(OBJECT_DEFINITION(@ObjectID))

クエリの正しい長さ (例: 5191) を返しますが、@SQLQuery1 を見たり、

EXEC(@SQLQuery1), the statement is still truncated.

c. クエリのテキストを取得した後に操作しているため、結果の変数は 4000 文字に切り捨てられると述べている参考文献がいくつかあります。REPLACE を実行するときに、結果を CAST しようとしました。

SET @SQLQueryNew1 = SELECT (CAST(REPLACE(@SQLQueryNew1, 
                                 'Company_A', 
                                 @CompanyID) AS varchar(max))

同じ結果です。

ビューを作成するためのストアド プロシージャを作成するなど、他の方法があることは知っています。しかし、ビューは開発中であり、やや「流動的」であるため、ストアド プロシージャ内に CREATE VIEW のテキストを配置するのは面倒です。私の目標は、Company_A のビューを取得して正確に複製できるようにすることです。ただし、Company_B のビュー名とテーブル名、Company_C のビュー名とテーブル名などを参照する場合を除きます。

長い SQL の "CREATE VIEW" ステートメントをこの種の操作を行って実行しようとした人がいるかどうか疑問に思っています。

4

2 に答える 2

6

VARCHAR(MAX)またはNVARCHAR(MAX)を使用してください。それらはEXEC(string)に対して正常に機能します。


ご参考までに、

これは、SQL が長い定義を保存する方法であることに注意してください。ビューを作成すると、テキストが複数の syscomments レコードに保存されます。

これは正しくありません。これは、SQL Server 2000 で行われていた方法です。SQL Server 2005 以降では、sys.sql_modulesの単一のエントリに NVARCHAR(MAX) として保存されます。

syscommentsはまだありますが、互換性のためだけに読み取り専用のままになっています。


したがって、@SQLQuery1、2 などを変更するだけで済みます。変数を単一の NVARCHAR(MAX) 変数に変換し、代わりに sys.sql_modules テーブルの [definition] 列からビュー コードをプルします。

すべての入力引数が (N)VARCHAR(MAX) でない場合、(N)VARCHAR(4000) 出力に戻る特定の関数があるため、文字列操作には注意する必要があります。(申し訳ありませんが、どれかわかりませんが、REPLACE() が 1 つかもしれません)。実際、これがテストで多くの混乱を引き起こしている原因かもしれません。

于 2012-04-22T20:17:15.610 に答える
0

各SQL部分が4000バイトを超えていないことを確認するために、SQL変数(@SQLQuery1 ...)を宣言しますnvarchar(4000) (各部分をテキストファイルにコピーし、ファイルサイズをバイト単位でテストします)

于 2014-03-12T10:09:13.047 に答える