Sql 单进程中的两个进程?

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

我是SQL Server 2008的新手。我正在使用三个表。我已经为我的结果创建了两个进程。但我希望这两个进程组合在一个进程中。 下面是我的程序-

第一道工序-

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 ...
然而,由于返回的记录看起来不太相似,我将坚持使用两个过程,用于两种不同的场景


对于参数的所有可能值:

  • 如果只有几个(可枚举)选项,让我们将它们称为Column1、Column2和Column3,您可以这样使用:

    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,但要非常注意sql注入之类的问题(这是一篇很棒的文章,当我需要动态sql时,我总是使用它)


  • 无论是谁向您展示了这种存储过程模板,都是错误的。动态查询执行在少数情况下是有用的,但在您的情况下,它只会带来过度的杀伤力以及性能和安全隐患。程序应为:

    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 ...
    
    然而,由于返回的记录看起来不太相似,我将坚持使用两个过程,用于两种不同的场景


    对于参数的所有可能值:

  • 如果只有几个(可枚举)选项,让我们将它们称为Column1、Column2和Column3,您可以这样使用:

    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,但要非常注意sql注入之类的问题(这是一篇很棒的文章,当我需要动态sql时,我总是使用它)


  • 首先,摆脱“构建字符串并执行”的方法。它使您暴露于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语句根据输入参数返回不同的列即可。不需要丑陋的字符串操作…请告诉我如何操作?谢谢你的回复。您的查询中有一个问题,我已经遇到了,我在进程中使用了字符串。如果