Sql 单进程中的两个进程?
我是SQL Server 2008的新手。我正在使用三个表。我已经为我的结果创建了两个进程。但我希望这两个进程组合在一个进程中。 下面是我的程序- 第一道工序-Sql 单进程中的两个进程?,sql,sql-server-2008,stored-procedures,Sql,Sql Server 2008,Stored Procedures,我是SQL Server 2008的新手。我正在使用三个表。我已经为我的结果创建了两个进程。但我希望这两个进程组合在一个进程中。 下面是我的程序- 第一道工序- CREATE PROC [GetPaymentGateway] @CompanyID VARCHAR(3), @CCMSalesChannel VARCHAR(50) AS declare @mainquery varchar(max) set @mainquery='SELECT credit_card_ma
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)
第二道工序-
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)
请建议我。是否可以使用哈希表等
提前谢谢
编辑-我希望将这两个结果放在一个结果中(就像放在一个表中一样)
编辑-我的表中有五列,但我将选择哪一列,它将根据参数在运行时了解。除非绝对必要,否则应避免在存储过程中执行此类SQL,并且1000%确保正确清理输入。事实上,所有输入参数都是varchar,而且这些似乎是用于检索支付信息的存储过程,至少可以说是令人不安的。通过在进程内执行这种动态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
您应该避免在存储过程中使用这种SQL,除非这是绝对必要的,并且您有1000%的把握正确地清理了输入。事实上,所有输入参数都是varchar,而且这些似乎是用于检索支付信息的存储过程,至少可以说是令人不安的。通过在进程内执行这种动态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
无论是谁向您展示了这种存储过程模板,都是错误的。动态查询执行在少数情况下是有用的,但在您的情况下,它只会带来过度的杀伤力以及性能和安全隐患。程序应为:
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 [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
SELECT
case when @NBSalesChannel='Column1' then Column1
when @NBSalesChannel='Column2' then Column2
when @NBSalesChannel='Column3' then Column3
else null
end as NBSalesChannel
FROM ...
然而,由于返回的记录看起来不太相似,我将坚持使用两个过程,用于两种不同的场景
对于参数的所有可能值:
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
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 ...
无论是谁向您展示了这种存储过程模板,都是错误的。动态查询执行在少数情况下是有用的,但在您的情况下,它只会带来过度的杀伤力以及性能和安全隐患。程序应为:
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 [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
SELECT
case when @NBSalesChannel='Column1' then Column1
when @NBSalesChannel='Column2' then Column2
when @NBSalesChannel='Column3' then Column3
else null
end as NBSalesChannel
FROM ...
然而,由于返回的记录看起来不太相似,我将坚持使用两个过程,用于两种不同的场景
对于参数的所有可能值:
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
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注入中,对性能不利。在数据库中,您可以只写(例如)“select*from table where company_id=@companyID”。不回答您的问题,但您可以考虑用声明的参数和sp_executesql-替换字符串链接。这将有助于缓存查询计划,并提供一些针对注入攻击的保护。@ObiWanKenobi-是的,你是对的。但我有个问题。我必须选择一个基于proc参数(@NBSalesChannel)的运行时列。所以我做了这个way@Mohit:如果需要在运行时选择不同的列,只需使用CASE语句根据输入参数返回不同的列即可。不需要丑陋的字符串操作…请告诉我如何操作?首先,摆脱“构建字符串并执行”的方法。它使您暴露于SQL注入中,对性能不利。在数据库中,您可以只写(例如)“select*from table where company_id=@companyID”。不回答您的问题,但您可以考虑用声明的参数和sp_executesql-替换字符串链接。这将有助于缓存查询计划,并提供一些针对注入攻击的保护。@ObiWanKenobi-是的,你是对的。但我有个问题。我必须选择一个基于proc参数(@NBSalesChannel)的运行时列。所以我做了这个way@Mohit:如果需要在运行时选择不同的列,只需使用CASE语句根据输入参数返回不同的列即可。不需要丑陋的字符串操作…请告诉我如何操作?谢谢你的回复。您的查询中有一个问题,我已经遇到了,我在进程中使用了字符串。如果