Два Proc в одном Proc? - PullRequest
       2

Два Proc в одном Proc?

0 голосов
/ 13 сентября 2011

Я новичок в SQL Server 2008. Есть три таблицы, которые я использую. Я создал два Proc для моего результата. Но я хочу, чтобы эти два Proc объединились в один 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)

Второй процесс -

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)

Пожалуйста, предложите мне. Возможно ли это с помощью хеш-таблицы и т. Д.

Заранее спасибо.

РЕДАКТИРОВАТЬ - Я хотел, чтобы эти два результата были в одном результате (как в одной таблице)

РЕДАКТИРОВАТЬ - В моей таблице пять столбцов, но какой из них я выберу, он узнает во время выполнения на основе параметра.

Ответы [ 2 ]

3 голосов
/ 13 сентября 2011

Вам следует избегать выполнения такого рода 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
1 голос
/ 13 сентября 2011

Кто бы ни показал вам этот тип шаблона для хранимых процедур, он сделал это неправильно.Динамическое выполнение запроса может быть полезно в нескольких сценариях, но в вашем случае это просто перебор, а также риски для производительности и безопасности.Процедуры должны быть:

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

При этом, чтобы присоединиться к ним в одном процессе, вы можете передать дополнительный параметр, который будет определять, какой запрос выполнить,и соответственно вернуть результаты, например:

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

Однако, поскольку кажется, что возвращенные записи не очень похожи, я бы придерживался двух процедур для двух разных сценариев.


Для всех возможных значений параметра:

  1. если есть только несколько (перечислимых) опций, давайте назовем их Column1, Column2 и Column3, вы можете использовать искомое выражение регистра как это:

    SELECT 
      case when @NBSalesChannel='Column1' then Column1
           when @NBSalesChannel='Column2' then Column2
           when @NBSalesChannel='Column3' then Column3
           else null
      end as NBSalesChannel
    FROM ...
    
  2. Вы можете просто выбрать все возможные столбцы и использовать код на стороне приложения, чтобы получить то, что вы хотите - у вас будут некоторые накладные расходыздесь, но запросы будут проще

    SELECT Column1, Column2, Column3
    FROM ...
    
  3. Если вы не знаете, какие столбцы доступны, то в качестве крайней меры используйте динамический sql, но помните о таких проблемах, как SQLИнъекция ( this - отличная статья, которую я всегда использую, когда мне кажется, что мне нужен динамический SQL)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...