0

データベースの作成を半自動化しようとしています。その一環として、列の説明の拡張プロパティを追加したいと思います。スクリプトでsp_sqlexecを実行しようとすると(またはExec(@mystring)だけでもエラーが発生します。ただし、デバッグ中に動的SQL文字列を監視ウィンドウからコピーしてから、コピーした文字列に対して別の文字列でsp_sqlexecを実行します。ウィンドウエラーは発生せず、拡張プロパティが正しく追加されます。次のスクリプトは問題を示しています。

--Create a table to apply column descriptions to 

Create table dbo.table1 (id int, name nvarchar(20));

--Create the table that contains our column descriptions

Create table dbo.column_descs_table (schemaname nvarchar(20), tablename nvarchar(20), columnname nvarchar(20), column_description nvarchar(20))

Insert into column_descs_table (schemaname, tablename, columnname, column_description)
values ('dbo', 'table1', 'id', 'the id column'), ('dbo' , 'table1', 'name', 'the name column');

--Dynamic sql string varaible to hold the commands
Declare @dyn_sql nvarchar(max);
Set @dyn_sql = 'N'''; --Set to opening quote 

--now create the string containing commands to add column escriptions
SELECT @dyn_sql = @dyn_sql + N' EXEC sp_addextendedproperty ''''Col Desc'''', ''''' + column_description + N''''', ''''SCHEMA'''', ' + schemaname +  N', ''''TABLE'''', ' + tablename + N', ''''COLUMN'''', ' + columnname + N' ;'   
FROM dbo.column_descs_table

Set @dyn_sql = @dyn_sql + ''''; --add the closing quote

Print @dyn_sql --If I copy the contents of @dyn_sql here and run seperately it works OK

Exec sp_sqlexec @dyn_sql -- this line causes error

私が得るエラーは、メッセージ102、レベル15、状態1、行1です。'EXEC sp_addextendedproperty' Col Desc'、' id column'、' SCHEMA'、dbo、' TABLE'、table1、' COLUMN'、idの近くの構文が正しくありません。 ; EXECsp_addextendedprope'。

しかし、コードをステップ実行して@dyn_sqlの内容をコピーすると、次のように貼り付けられます。

Exec sp_sqlexec N'EXEC sp_addextendedproperty''Col Desc''、''id column''、''SCHEMA''、dbo、''TABLE''、table1、''COLUMN''、id; EXEC sp_addextendedproperty'' Col Desc''、'' name column''、'' SCHEMA''、dbo、'' TABLE''、table1、'' COLUMN''、name; '

次に、上記が正常に機能し、列の説明が期待どおりに追加されます。

この特定のコピーの問題に関する助けは大歓迎です。動的SQLのセキュリティ問題を理解しています(セットアップが完了すると、このスクリプトはデータベースから削除されます)

前もって感謝します

ジュード

4

2 に答える 2

0

文字列のコピーの問題は解決したと思います。SQLは、連結された文字列を空の文字列として二重引用符で囲んで検出し、それらを削除していました。問題と私の解決策を示す簡単な例を以下に示します。

--Example to Select 'simple string' and then 'concat string' into results sets
DECLARE
   @Simplestring nvarchar( max ) = '' , 
   @Concatstring nvarchar( max ) = '' ,
   @Stringvar nvarchar( 10 ) = 'string';

--The double quotes in next line are the quotemark we want plus a quotemark acting 
--as an escape character
--@simplestring will be set to 'Select 'simple string' '
SET @Simplestring = 'Select ''simple string'' ';

--Similarly we need @concatstring to be set to 'Select 'Concat string' '
SET @Concatstring = 'Select  '' concat' + @Stringvar + ''; -- this wont work the last 
--double quote will be removed

--Add a character that cannot appear in any othe part of the concatenation - I've used *
SET @Concatstring = 'Select '' Concat ' + @Stringvar + '*';
--Now replace the * with a quote mark
SET @Concatstring = REPLACE( @Concatstring , '*' , '''' ); -- This will work

EXEC sp_executesql @Simplestring;  
EXEC sp_executesql @Concatstring;

私よりも簡単な解決策があるかもしれません。

sp_executesqlの使用に関するアドバイスに感謝します。これを使用するようにコードを変更しています(変数はパラメーターとして渡されます)。

ジュード

于 2012-05-18T13:11:57.157 に答える
0

先頭の N が実行する文字列に含まれているためのようです。まったく必要ありません。つまり、次のような結果になります。

exec sp_execsql 'N'' exec sp_addextendedproperty /* etc. */ '''

しかし、次のようにする必要があります。

exec sp_execsql N'exec sp_addextendedproperty /* etc. */ '

しかし、なぜここで動的 SQL を使用しているのですか? sp_addextendedproperty に渡されるすべての値はパラメーターとして渡すことができるため、質問のために何かを単純化しない限り、動的 SQL を使用する明らかな理由はありません。

最後に、sp_executesql を使用する必要があります。これは、動的 SQL を実行するための推奨される方法です。

于 2012-05-15T11:27:36.987 に答える