我被要求创建一个存储过程,它将接受许多选项(目前有八个布尔值)来指示包含哪些列。
我可以为每种情况创建一个单独的SELECT
语句,但是8²(八方)= 64个单独的select语句。再添加1个参数,我现在有9²= 81个单独的select语句。这很快就会增加。
我正在使用Microsoft的SQL Server Management Studio(SSMS),因为我不是一个强大的SQL编写器,它告诉我什么时候我做错了。
如果我构建一个动态SQL语句,我将失去SSMS的代码检查能力。
问:有没有办法使用参数值指定SELECT
语句列?
这是一个非常粗略的例子,我尝试使用SQL Fiddle拼凑在一起:
http://sqlfiddle.com/#!3/5ef0f/1
架构:
create table Invoice
(
Id int IDENTITY(1,1) NOT NULL,
Name varchar(20) NOT NULL,
Retail decimal(9, 4) NOT NULL,
Quoted decimal(9, 4) NOT NULL,
TaxCodeId int NULL
);
create table TaxCode
(
Id int IDENTITY(1,1) NOT NULL,
Name varchar(20) NOT NULL,
Rate decimal(9, 4) NOT NULL
);
存储过程:
CREATE PROCEDURE TestProcedure
(@showPrice bit, @showTaxRate bit)
AS BEGIN
SET NOCOUNT ON;
SELECT
Invoice.Name,
CASE WHEN @showPrice = 1 THEN Invoice.Retail, Invoice.Quoted,
END
CASE WHEN @ShowTaxRate = 1 THEN TaxCode.Rate
END
FROM
Invoice
LEFT JOIN
TaxCode on Invoice.TaxCodeId = TaxCode.Id;
END;
答案 0 :(得分:3)
你已经找到了两个选项和每个选项的缺点。
您可以使用:
没有别的办法。
如果您担心失去SSMS的代码检查能力,可以在开发期间使用PRINT语句来查看动态查询的外观,并将该查询复制并粘贴到新的SSMS查询中以查看SSMS可能具有的建议
答案 1 :(得分:2)
一种方法是使用DECLARE @showPrice BIT = 1
,@showTaxRate BIT = 0;
DECLARE @sql NVARCHAR(MAX) =
N'SELECT i.Name,i.Retail,i.Quoted,tc.Rate
FROM Invoice i
LEFT JOIN TaxCode tc
ON i.TaxCodeId=tc.Id;';
IF @showPrice = 0
SET @sql = REPLACE(@sql, ',i.Retail,i.Quoted', '');
IF @showTaxRate = 0
SET @sql = REPLACE(@sql, ',tc.Rate', '');
EXEC dbo.sp_executesql @sql;
(连接列列表或从列列表中排除)
DROP column
的 LiveDemo
强>
第二种丑陋的方式是使用临时表和DECLARE @showPrice BIT = 1
,@showTaxRate BIT = 0;
SELECT i.Name,i.Retail,i.Quoted,tc.Rate
INTO #temp
FROM Invoice i
LEFT JOIN TaxCode tc
ON i.TaxCodeId=tc.Id;
IF @showPrice = 0
ALTER TABLE #temp DROP COLUMN Retail, Quoted;
IF @showTaxRate = 0
ALTER TABLE #temp DROP COLUMN Rate;
-- if you use it within SP you need to wrap it with `EXEC`
-- EXEC('ALTER TABLE #temp DROP COLUMN Rate;');
SELECT * FROM #temp;
:
context.CITies.Find(comId1, comId2);
的 LiveDemo2
强>