質問でデータベース製品を指定していませんが、@Pararemterの命名スタイルからSQLServerを使用していると推測します。
空の入力を「すべて」を意味するように解釈するという珍しい要件を除いて、これはSQLの配列の問題の言い換えであり、ErlandSommarskogによって徹底的に調査されました。あなたが使用できるすべてのテクニックの良い分析のために主題に関する彼のすべての記事を読んでください。
ここでは、テーブル値パラメーターを使用して問題を解決する方法を説明します。
次のスクリプトをすべて一緒に実行して、べき等な方法でテスト環境をセットアップします。
サンプルソリューションの作成
まず、新しい空のテストデータベースを作成しますStackOverFlow13556628
。
USE master;
GO
IF DB_ID('StackOverFlow13556628') IS NOT NULL
BEGIN
ALTER DATABASE StackOverFlow13556628 SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE StackOverFlow13556628;
END;
GO
CREATE DATABASE StackOverFlow13556628;
GO
USE StackOverFlow13556628;
GO
次に、PrinciapalList
1つの列を持つユーザー定義のテーブルタイプを作成しますprincipal_id
。このタイプには、システムテーブルをクエリするための入力値が含まれていますsys.database_principals
。
CREATE TYPE PrincipalList AS TABLE (
principal_id INT NOT NULL PRIMARY KEY
);
GO
その後、テーブル値パラメーターを入力として受け取り、から結果セットを返すストアドプロシージャGetPrincipals
を作成します。PrincipalList
sys.database_principals
CREATE PROCEDURE GetPrincipals (
@principal_ids PrincipalList READONLY
)
AS
BEGIN
IF EXISTS(SELECT * FROM @principal_ids)
BEGIN
SELECT *
FROM sys.database_principals
WHERE principal_id IN (
SELECT principal_id
FROM @principal_ids
);
END
ELSE
BEGIN
SELECT *
FROM sys.database_principals;
END;
END;
GO
sys.database_principals
table-valuedパラメーターに行が含まれている場合、プロシージャーは、値が一致するすべての行を返しprincipal_id
ます。table-valuedパラメーターが空の場合、すべての行が返されます。
ソリューションのテスト
次のように複数のプリンシパルをクエリできます。
DECLARE @principals PrincipalList;
INSERT INTO @principals (principal_id) VALUES (1);
INSERT INTO @principals (principal_id) VALUES (2);
INSERT INTO @principals (principal_id) VALUES (3);
EXECUTE GetPrincipals
@principal_ids = @principals;
GO
結果:
principal_id name
1 dbo
2 guest
3 INFORMATION_SCHEMA
次のように単一のプリンシパルをクエリできます。
DECLARE @principals PrincipalList;
INSERT INTO @principals (principal_id) VALUES (1);
EXECUTE GetPrincipals
@principal_ids = @principals;
GO
結果:
principal_id name
1 dbo
次のようにすべてのプリンシパルにクエリを実行できます。
EXECUTE GetPrincipals;
結果:
principal_id name
0 public
1 dbo
2 guest
3 INFORMATION_SCHEMA
4 sys
16384 db_owner
16385 db_accessadmin
16386 db_securityadmin
16387 db_ddladmin
16389 db_backupoperator
16390 db_datareader
16391 db_datawriter
16392 db_denydatareader
16393 db_denydatawriter
備考
このソリューションは、テーブル値パラメーターから常に2回読み取る必要があるため、非効率的です。実際には、テーブル値パラメーターに数百万行が含まれていない限り、それが主要なボトルネックになることはおそらくありません。
このように空のテーブル値パラメーターを使用すると、直感的ではないと感じます。より明白な設計は、2つのストアドプロシージャを持つことです。1つはすべての行を返し、もう1つは一致するIDを持つ行のみを返します。どちらを呼び出すかを選択するのは、呼び出し元のアプリケーション次第です。