テーブルの名前をストアドプロシージャに渡すことはできますか?
たとえば、同じテーブルの複数のビューがあるとします。それらはすべてまったく同じ構造です。
どのビューでも実行できるストアドプロシージャが必要です。
何かのようなもの:
create procedure myprocedure
@tableName varchar(50) = ''
select blah from @tableName where blah = blah2
これをやろうとすると、
Must declare the table variable @tablename
どうすればこれを行うことができますか?
ビューを作成する代わりに、インラインテーブル値関数を作成してみませんか-効果的にパラメーター化されたビュー。基本的には、ビューとパラメーターのすべての利点が得られます。
TVFで実行できるもう1つのことは、次のようなものです。
SELECT yourtable.*
FROM yourtable
INNER JOIN ranges
ON yourtable.date BETWEEN ranges.start AND ranges.end
WHERE ranges.name = @range_name
これで範囲に名前が付けられました(スキーマを変更せずに簡単に管理できるテーブル内)。これにより、同じ名前の複数の範囲もかなりシームレスに処理されます。ただし、範囲が重複している場合は、結合が両方に一致するため、重複する可能性があります。
また、BETWEENの回避を検討してください。
要件を再検討することを強くお勧めします。ここで質問をするときは、動機についての詳細を含めるようにしてください。ソリューションが何であるかについての先入観を持った質問をすると、次善のソリューションが得られる可能性が高いためです。 (与えられた動的SQLソリューションのように、ORの場合は簡単に機能しませんが、問題のスペースに関する情報はあなたからのコメントに埋め込まれています)
差出人: http://sqlfiddle.com/#!6/a628a/1
CREATE TABLE LogData (
Id INT IDENTITY NOT NULL
,Dt DATETIME NOT NULL
,Data VARCHAR(max) NOT NULL
);
CREATE TABLE Ranges (
Id INT IDENTITY NOT NULL
,Name VARCHAR(50) NOT NULL
,DtStart DATETIME NOT NULL
,DtEnd DATETIME NOT NULL
);
CREATE TABLE Groups (
Id INT IDENTITY NOT NULL
,Name VARCHAR(50) NOT NULL
);
CREATE TABLE RangeGroups (
RangeId INT NOT NULL
,GroupId INT NOT NULL
);
INSERT INTO LogData (Dt, Data)
VALUES ('2011-11-23 11:00', 'before thanksgiving day')
,('2011-11-24 11:00', 'on thanksgiving day')
,('2011-12-24 11:00', 'on christmas eve')
,('2011-12-25 11:00', 'on christmas day')
,('2012-11-21 11:00', 'before thanksgiving day')
,('2012-11-22 11:00', 'on thanksgiving day')
,('2012-12-24 11:00', 'on christmas eve')
,('2012-12-25 11:00', 'on christmas day');
INSERT INTO Ranges (Name, DtStart, DtEnd)
VALUES ('THANKSGIVING2011', '2011-11-24', '2011-11-25')
,('CHRISTMASEVE2011', '2011-12-24', '2011-12-25')
,('CHRISTMASDAY2011', '2011-12-25', '2011-12-26')
,('BOXINGDAY2011', '2011-12-26', '2011-12-27')
,('NEWYEARSEVE2011', '2011-12-31', '2012-01-01')
,('NEWYEARSDAY2012', '2012-01-01', '2012-01-02')
,('THANKSGIVING2012', '2012-11-22', '2012-11-23')
,('CHRISTMASEVE2012', '2012-12-24', '2012-12-25')
,('CHRISTMASDAY2012', '2012-12-25', '2012-12-26')
,('BOXINGDAY2012', '2012-12-26', '2012-12-27')
,('NEWYEARSEVE2012', '2012-12-31', '2013-01-01')
,('NEWYEARSDAY2013', '2013-01-01', '2013-01-02');
INSERT INTO Groups (Name)
VALUES ('HOLIDAYS2011')
,('HOLIDAYS2012')
,('ANYCHRISTMAS');
INSERT INTO RangeGroups (RangeId, GroupId)
SELECT Id, (SELECT Id FROM Groups WHERE Name = 'HOLIDAYS2011')
FROM Ranges WHERE Name LIKE '%2011';
INSERT INTO RangeGroups (RangeId, GroupId)
SELECT Id, (SELECT Id FROM Groups WHERE Name = 'HOLIDAYS2012')
FROM Ranges WHERE Name LIKE '%2012';
INSERT INTO RangeGroups (RangeId, GroupId)
SELECT Id, (SELECT Id FROM Groups WHERE Name = 'ANYCHRISTMAS')
FROM Ranges WHERE Name LIKE 'CHRISTMAS%';
CREATE FUNCTION dbo.JustDoIt(@GroupName VARCHAR(50))
RETURNS TABLE
RETURN (
SELECT LogData.*
FROM LogData
INNER JOIN Ranges ON LogData.Dt >= Ranges.DtStart
AND LogData.Dt < Ranges.DtEnd
INNER JOIN RangeGroups
ON RangeGroups.RangeId = Ranges.Id
INNER JOIN Groups
ON Groups.Id = RangeGroups.GroupId
AND Groups.Name = @GroupName
);
SELECT *
FROM dbo.JustDoIt('HOLIDAYS2011');
SELECT *
FROM dbo.JustDoIt('HOLIDAYS2012');
SELECT *
FROM dbo.JustDoIt('ANYCHRISTMAS');
この部分:
SELECT LogData.*
FROM LogData
INNER JOIN Ranges ON LogData.Dt >= Ranges.DtStart
AND LogData.Dt < Ranges.DtEnd
INNER JOIN RangeGroups
ON RangeGroups.RangeId = Ranges.Id
INNER JOIN Groups
ON Groups.Id = RangeGroups.GroupId
AND Groups.Name = @GroupName
各ログアイテムが(日付によって)適合する範囲に結合され、各範囲はそれらが属するグループに結合されますが、選択されたグループのみが使用されます。
オブジェクト名はパラメーター化できません。
動的SQLを使用する必要があります。
_CREATE PROCEDURE MyProc
(
@schemaName sysname,
@tableName sysname,
@blah2 int
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @sql nvarchar(MAX)
SET @sql = N'SELECT blah FROM '
+ QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + N' WHERE blah = @blah2'
EXEC sp_executesql @sql, N'@blah2 int', @blah2
END
_
sysname
は(現在)nvarchar(128)
として定義されていることに注意してください。
私はあなたの最善の策はこれを達成するために動的SQLを使用することだと思います:
create procedure myprocedure
@tableName nvarchar(50) = ''
as
declare @sql_cmd nvarchar(200)
set @sql_cmd = 'select blah from ' + QUOTENAME(@tableName) + ' where blah = blah2'
exec (@sql_cmd)
go