私は基本的に同じことを行うストアドプロシージャが多数あります:パラメータとして値のリストを取得し、次にいくつかのテーブルとSELECTに移動しますこれらの値が一致するすべての行。T-SQL - 不明な型の未知数のパラメータを処理するストアドプロシージャ
これらのすべてのケースを処理できる単一のストアドプロシージャを用意したいと考えています。
これにどのように対処しますか?
私は基本的に同じことを行うストアドプロシージャが多数あります:パラメータとして値のリストを取得し、次にいくつかのテーブルとSELECTに移動しますこれらの値が一致するすべての行。T-SQL - 不明な型の未知数のパラメータを処理するストアドプロシージャ
これらのすべてのケースを処理できる単一のストアドプロシージャを用意したいと考えています。
これにどのように対処しますか?
を使用して、それを呼び出すことができます。 XMLを入力パラメーターとして送信します。 xmlをテーブルに変換します。テーブルフォームから動的クエリを実行して、目的の機能を実現します。以下の例を参照してください。この例では、Departmentsは3つの列pkDepartmentId(int)、DepartmentName(varchar)およびBuildingNumber(int)を含む表です。この方法を使用すると、n個のパラメータとその値を入力パラメータとして送信できます。
pkDepartmentId DepartmentName BuildingNumber 1電子通信1 2コンピュータサイエンス2 3計測し、その結果、次のこのPROCを実行する上での技術4
--EXEC TestProc '<Parameters>
-- <Param>
-- <ColumnName>pkDepartmentId</ColumnName>
-- <ColumnValue>1</ColumnValue>
-- </Param>
-- <Param>
-- <ColumnName>DepartmentName</ColumnName>
-- <ColumnValue>Electronics and Communication</ColumnValue>
-- </Param>
-- <Param>
-- <ColumnName>BuildingNumber</ColumnName>
-- <ColumnValue>1</ColumnValue>
-- </Param>
-- </Parameters>'
CREATE PROCEDURE TestProc
@parameters XML
AS
BEGIN
DECLARE @temp1 TABLE
(
ColName VARCHAR(100)
, ColVal VARCHAR(4000)
)
INSERT INTO @temp1
SELECT Params.Col.value('ColumnName[1]', 'VARCHAR(50)') ColName
, Params.Col.value('ColumnValue[1]', 'VARCHAR(50)') ColVal FROM @parameters.nodes('//Parameters/Param') Params(Col)
DECLARE @sql VARCHAR(4000)
SET @sql = 'SELECT * FROM Departments WHERE '
SELECT @sql = @sql + ColName + ' = ''' + ColVal + ''' AND '
FROM @temp1
-- Trim last AND
SET @sql = SUBSTRING(@sql, 1, LEN(@sql) - 3)
PRINT @sql
EXEC (@sql)
END
は pkDepartmentId DepartmentName BuildingNumber 1つの電子通信1
を得ていますXMLと 'DECLARE @ temp1 TABLE'テーブルに' ColumnType'が表示されませんか?また、 '@ sql'文字列をSQLインジェクションに対して脆弱にするように構築します。もしXMLから取り出す変数を' DECLARE'したいのであれば '@ sql'で使うことができます@sql = 'SELECT * FROM Departments WHERE id = @id AND firstName = @ firstName''のようなものを作成できますか? – rapt
こんにちはRapt、私はColumnTypeを削除するコードを変更しました。変数を宣言してSQL文字列を作成する場合は、カーソルまたはwhileループを使用して@temp Tableのすべてのレコードをループする必要があります。 –
ありがとう、とても助かりました! – rapt
デフォルトパラメータ:
create procedure MyPRoc1
(
@param1 int,
@param2 int =1
)
as
begin
--code
end
あなたは、あなたの問題のためのXMLベースのアプローチを使用しようとすることができ
exec MyPRoc1 10
または
exec MyPRoc1 1,1
しないでください。すべてのデータベースのパフォーマンスを低下させようとしています。 T-SQLとコードの再利用は混在しません。
あなたはになりますか?これらのストアドプロシージャはすべて自動的に生成されます。これを行う多くのツールがあります。独自の方法を簡単に使用することができます.SQLを使用してテーブル定義をXMLに抽出し、XSLTを使用してこれをT-SQLに変換し、procを生成します。プロジェクトのビルドと連続した統合プロセスに自動化することができます。強力なタイプ、効率的なT-SQLコード、さらには機敏でDRY性の高い保守可能なプロセスにより、100種類のprocsを1回の変更で簡単に書き直すことができます。
あなたはどのような再利用をしていますか? SQLクエリを動的に作成しますか? – rapt
テーブル値のパラメータTVP(SQL Serverのバージョンが> = 2008の場合)はどうですか?しかし、これは "未知の型"の部分を解決しません。私は...あなたがvarchar型(最大)、あるいはNVARCHAR(max)を使用し、必要に応じてそれをキャストしなければならないと思い
は参照:SQL Serverの以前のバージョンのhttp://www.sommarskog.se/arrays-in-sql-2008.html
、以下を参照してください。
も、このためにストアドプロシージャを使用してのポイントは何ですか?動的なSQLが必要になるため、プランのキャッシュや所有権の連鎖の恩恵を受けることはありません。それぞれのケースに対して別々のストアドプロシージャを用意するだけです。 –
例を示してください。 –
可変数の仮パラメータを持つ単一のsprocを現在使用できるとは思わない:http://stackoverflow.com/questions/7653405/expression-parameter-data-types-for-user-defined-functions-おそらくcodegen T4などを介して – AakashM