web-dev-qa-db-ja.com

ワンライナーSQLステートメントで改行を含むストアドプロシージャを作成する

改行を含むストアドプロシージャを作成するコードを1行で記述したいと思います。

  • それは可能ですか?
  • Sp_executesqlを使用する必要がありますか?
  • SQLステートメントで改行をエスケープするにはどうすればよいですか?
  • 文字列の改行をエスケープするにはどうすればよいですか?
2
Anders Lindén

はい、動的SQLで次のようなことができます。

DECLARE @SQL NVARCHAR(MAX) = N'';
DECLARE @NewLine NCHAR(1) = NCHAR(10);

SET @SQL = @SQL + N'SELECT * ' + @NewLine + N'FROM sys.databases AS d ' + @NewLine + N'WHERE d.database_id > 4;' + @NewLine;

PRINT @SQL;
EXEC sys.sp_executesql @SQL;
6
Erik Darling

いいえ、T-SQLは改行や​​タブなどをエスケープできません。埋め込まれた文字列区切り文字のエスケープシーケンスのみがあります:'' = '。区切り識別子のエスケープシーケンスもあります。識別子の区切りに使用されているものに応じて、""の場合は"]]の場合は]です。

エスケープシーケンスを操作する場合は、REPLACE関数を使用して手動で行うことができます。

「コードの1行」の解釈方法に応じて、次のいずれかを実行できます。

IF (OBJECT_ID(N'tempdb..#TestProc') IS NOT NULL)
BEGIN
    DROP PROCEDURE #TestProc;
END;
GO

-- The following is technically a single line (with multiple commands):
DECLARE @SQL NVARCHAR(MAX) = N'CREATE PROCEDURE #TestProc\n(\n  @Param1 INT,\n  @Param2 NVARCHAR(128)\n)\nAS\nSET NOCOUNT ON;\n\nSELECT *\nFROM   tempdb.sys.sql_modules\nWHERE  [object_id] = OBJECT_ID(N''tempdb..'' + @Param2);'; SET @SQL = REPLACE(@SQL, N'\n', NCHAR(10)); EXEC (@SQL);

-- View the definition:
PRINT @SQL;

-- Test the proc:
EXEC #TestProc 2, N'#TestProc';

または、単一のコマンド/ステートメントしか実行できない場合は、以下を試すことができます。

IF (OBJECT_ID(N'tempdb..#TestProc2') IS NOT NULL)
BEGIN
    DROP PROCEDURE #TestProc2;
END;
GO

-- The following is a single line and a single statement:
EXEC (N'DECLARE @SQL NVARCHAR(MAX) = N''CREATE PROCEDURE #TestProc2\n(\n  @Param1 INT,\n  @Param2 NVARCHAR(128)\n)\nAS\nSET NOCOUNT ON;\n\nSELECT *\nFROM   tempdb.sys.sql_modules\nWHERE  [object_id] = OBJECT_ID(N''''tempdb..'''' + @Param2);''; SET @SQL = REPLACE(@SQL, N''\n'', NCHAR(10)); EXEC (@SQL);');

-- Test the proc:
EXEC #TestProc2 2, N'#TestProc2';

-- View the definition:
DECLARE @SQL2 NVARCHAR(MAX);
SELECT @SQL2 = [definition]
FROM   tempdb.sys.sql_modules
WHERE  [object_id] = OBJECT_ID(N'tempdb..#TestProc2');

PRINT @SQL2;
-- returns (in "Messages" tab):
/*
CREATE PROCEDURE #TestProc2
(
  @Param1 INT,
  @Param2 NVARCHAR(128)
)
AS
SET NOCOUNT ON;

SELECT *
FROM   tempdb.sys.sql_modules
WHERE  [object_id] = OBJECT_ID(N'tempdb..' + @Param2);
*/
0
Solomon Rutzky