我是SQL Server 2008的新手。我正在使用三个表。我已经为我的结果创建了两个Proc。但是我希望将这两个Proc组合在单个Proc中。 以下是我的过程 -
First Proc -
CREATE PROC [GetPaymentGateway]
@CompanyID VARCHAR(3),
@CCMSalesChannel VARCHAR(50)
AS
declare @mainquery varchar(max)
set @mainquery='SELECT credit_card_master.card_name, credit_card_master.card_type,'+ @CCMSalesChannel +' FROM credit_card_master
INNER JOIN PaymentGateway_master
ON PaymentGateway_master.payment_gateway_code = credit_card_master.payment_gateway_code
WHERE [company_id] = '''+@CompanyID+''''
exec (@mainquery)
Second Proc -
CREATE PROC [GetPaymentGateway2]
@CompanyID VARCHAR(3),
@NBSalesChannel VARCHAR(50)
AS
declare @mainquery varchar(max)
set @mainquery='SELECT PG_NetBanking_Charges.Online_DC_Charge_Amt, PaymentGateway_master.Payment_Gateway_Name,'+ @NBSalesChannel +' FROM PG_NetBanking_Charges
INNER JOIN PaymentGateway_master
ON PaymentGateway_master.payment_gateway_code = PG_NetBanking_Charges.payment_gateway_code
WHERE [company_id] = '''+@CompanyID+''''
exec (@mainquery)
请建议我。是否可以使用哈希表等。
提前致谢。
编辑 - 我希望这两个结果在单个结果中(如在单个表格中)
编辑 - 我的表格中有五列,但我会选择哪一列,它会根据参数在运行时间知道。
答案 0 :(得分:3)
除非绝对必要,否则你应该避免在存储过程中执行那种SQL,并且你有1000%确定你正确地清理输入。事实上,所有输入参数都是varchar,这些似乎是用于检索支付信息的存储过程,至少可以说是令人不安的。通过在procs中执行这种动态sql,你仍然容易受到SQL注入攻击。
两个过程都可以在一个过程中重写如下:
CREATE PROC [GetPaymentGateway]
@CompanyID VARCHAR(3),
@NBSalesChannel VARCHAR(50) =null,
@CCMSalesChannel VARCHAR(50) =null
AS
BEGIN
SELECT [card_name], [card_type],@CCMSalesChannel as CCMSalesChannel FROM credit_card_master
INNER JOIN PaymentGateway_master
ON PaymentGateway_master.payment_gateway_code = credit_card_master.payment_gateway_code
WHERE [company_id] = @CompanyID
SELECT PG_NetBanking_Charges.Online_DC_Charge_Amt, PaymentGateway_master.Payment_Gateway_Name, @NBSalesChannel as NBSalesChannel FROM PG_NetBanking_Charges
INNER JOIN PaymentGateway_master
ON PaymentGateway_master.payment_gateway_code = PG_NetBanking_Charges.payment_gateway_code
WHERE [company_id] = @CompanyID
END
或者你想要这个:
CREATE PROC [GetPaymentGateway]
@CompanyID VARCHAR(3),
@NBSalesChannel VARCHAR(50) =null,
@CCMSalesChannel VARCHAR(50) =null
AS
BEGIN
if (@CCMSalesChannel is not null)
begin
SELECT [card_name], [card_type],@CCMSalesChannel as CCMSalesChannel FROM credit_card_master
INNER JOIN PaymentGateway_master
ON PaymentGateway_master.payment_gateway_code = credit_card_master.payment_gateway_code
WHERE [company_id] = @CompanyID
end
else if (@NBSalesChannel is not null)
begin
SELECT PG_NetBanking_Charges.Online_DC_Charge_Amt, PaymentGateway_master.Payment_Gateway_Name, @NBSalesChannel as NBSalesChannel FROM PG_NetBanking_Charges
INNER JOIN PaymentGateway_master
ON PaymentGateway_master.payment_gateway_code = PG_NetBanking_Charges.payment_gateway_code
WHERE [company_id] = @CompanyID
end
END
更新通常,可以根据“运行时”的参数选择特定列,如下所示:
SELECT PG_NetBanking_Charges.Online_DC_Charge_Amt, PaymentGateway_master.Payment_Gateway_Name,
case @NBSalesChannel when 'value1' then ColumnA
when 'value2' then ColumnB
when 'anothervalue' then ColumnC
when 'yet_another_value' then ColumnD else
ColumnE end as SalesChannel
FROM PG_NetBanking_Charges
INNER JOIN PaymentGateway_master
ON PaymentGateway_master.payment_gateway_code = PG_NetBanking_Charges.payment_gateway_code
WHERE [company_id] = @CompanyID
答案 1 :(得分:1)
无论是谁为存储过程展示了这种模板,都是错误的。在少数情况下,动态查询执行可能很有用,但在您的情况下,只是过度杀伤,性能和安全隐患。程序应该是:
CREATE PROC [GetPaymentGateway]
@CompanyID VARCHAR(3)
AS
BEGIN
SELECT ccm.card_name, ccm.card_type,
-- all possible values for the @CCMSalesChannel param here
-- (unless there are 50 of them, in which case the db design is wrong)
FROM credit_card_master ccm
INNER JOIN PaymentGateway_master pm
ON pm.payment_gateway_code =ccm.payment_gateway_code
WHERE company_id = @CompanyID
END
和
CREATE PROC [GetPaymentGateway2]
@CompanyID VARCHAR(3)
AS
BEGIN
SELECT bc.Online_DC_Charge_Amt, m.Payment_Gateway_Name,
-- all possible values for the @NBSalesChannel param here
FROM PG_NetBanking_Charges bc
INNER JOIN PaymentGateway_master m
ON m.payment_gateway_code = bc.payment_gateway_code
WHERE company_id = @CompanyID
END
也就是说,要将它们连接到单个proc中,您可以传递一个额外的参数,该参数将决定运行哪个查询,并相应地返回结果,如下所示:
CREATE PROC [GetPaymentGateway]
@CompanyID VARCHAR(3),
@Type int
AS
if (@Type = 1)
BEGIN
SELECT ccm.card_name, ccm.card_type,
-- all possible values for the @CCMSalesChannel param here
FROM credit_card_master ccm
INNER JOIN PaymentGateway_master pm
ON pm.payment_gateway_code =ccm.payment_gateway_code
WHERE company_id = @CompanyID
END
ELSE IF (@Type = 2)
BEGIN
SELECT bc.Online_DC_Charge_Amt, m.Payment_Gateway_Name,
-- all possible values for the @NBSalesChannel param here
FROM PG_NetBanking_Charges bc
INNER JOIN PaymentGateway_master m
ON m.payment_gateway_code = bc.payment_gateway_code
WHERE company_id = @CompanyID
END
但是,由于看起来返回的记录不太相似,我会坚持两个程序,针对两种不同的情况。
对于参数的所有可能值:
如果只有少数(可枚举的)选项,我们称之为Column1,Column2和Column3,您可以像这样使用searched case expression:
SELECT
case when @NBSalesChannel='Column1' then Column1
when @NBSalesChannel='Column2' then Column2
when @NBSalesChannel='Column3' then Column3
else null
end as NBSalesChannel
FROM ...
您可以简单地选择所有可能的列并使用应用程序端代码来获取您想要的内容 - 这里会有一些开销,但查询会更简单
SELECT Column1, Column2, Column3
FROM ...
如果你不知道哪些列可用,那么作为最后的手段使用动态sql,但要非常清楚像SQL注入这样的问题(this是一篇很棒的文章,我总是使用它我需要动态SQL的接缝