2015-08-28 7 views
1

Я относительно новичок в расширенных запросах базы данных и хранимых процедурах, и у меня возникла проблема с третьим оператором UPDATE в следующей процедуре: в блоке кода IF. Проблема в том, что мне нужно добавить номера участников в эти учетные записи, поэтому первая итерация UPDATE добавляет lp.ID_1 к моей временной таблице, а вторая итерация добавляет lp.ID_2 во временную таблицу. Третьей итерации необходимо взять оставшиеся строки из оригинального оператора INSERT (где ident все еще должно быть NULL) и объединить столбец ident с ID_1 и ID_2, так как эти учетные записи имеют оба членства.SQL IF Условие в хранимой процедуре

Я пробовал несколько условий в блоке IF, но, похоже, каждый раз придумывал решение.

USE [database_1] 
GO 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[stored_procedure_1] @acct char(8) 

AS 

WITH X AS 
(
    select distinct st.ship2, t.name, null AS ident 
    from sales_table st 
    INNER JOIN accounts_table t ON st.ship2 = t.acct 
    where st.bill2 = @acct 
) 
SELECT x.ship2 AS s_acct 
     ,x.name 
     ,COALESCE(ident, lp.ID_1 +', '+ lp.ID_1 , lp.ID_2 , lp.ID_2 , '') AS Ident 
FROM X 
LEFT JOIN lp_table lp ON x.ship2 = lp.acct COLLATE Latin1_General_CS_AS 
WHERE COALESCE(ident, lp.ID_2 +', '+ lp.ID_1 , lp.ID_1 , lp.ID_2 , '') <> '' 

select * from X 
where ident is not null 
+1

Вы пытались удалить инструкцию if, и просто вызывать вызов 'UPDATE'? У вас есть чек, если идентификатор равен null, поэтому он должен делать то, что вы ожидаете от него. –

+1

"' взять оставшиеся строки ... и объединить столбец идентификатора с ID_1 и ID_2, так как эти учетные записи имеют оба члена. '" Нет! ** Не делай этого! ** Это некорректная схема. Если учетные записи могут иметь несколько членских составов, вам нужна отдельная таблица для сопоставления счетов для членства. ** НИКОГДА ** не вставлять данные csv в столбец! –

+0

@JohnOdom, если я удалю условие '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Другими словами, он работает так, как будто последнего 'UPDATE' не было. – soundwave

ответ

2

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

;WITH X AS 
(
    select distinct st.ship2, t.name, null AS ident 
    from sales_table st 
    INNER JOIN account_table t ON st.ship2 = t.acct 
    where st.bill2 = @acct 
) 
SELECT x.ship2 AS s_acct 
     ,x.name 
     ,COALESCE(ident, lp.ID_2 +', '+ lp.ID_1 , lp.ID_1 , lp.ID_2 , '') AS Ident 
FROM X 
LEFT JOIN lp_table lp ON x.ship2 = lp.acct COLLATE Latin1_General_CS_AS 
WHERE COALESCE(ident, lp.ID_2 +', '+ lp.ID_1 , lp.ID_1 , lp.ID_2 , '') <> '' 
+0

Где находится' X'? – soundwave

+0

'X' - это имя CTE' Common Table expression ', возможная замена временной таблицы в вашем случае. –

+0

Хорошо, мне нравится, когда это происходит, но я не совсем уверен, как реализовать это в хранимой процедуре. Я получаю сообщение об ошибке, что 'x.ship2'' x.name' не может быть привязан – soundwave

0

Второй запрос на обновление не будет работать. Первый запрос обновления обновляет все идентификационные значения строк #temp_table, которые имеют соответствующий «acct» с lp_table. Второй запрос рассматривает точно такой же набор строк, который вы только что обновили, добавив условие, в котором вас интересуют только те, где ident - null .... однако на первом шаге вы просто убедились, что ни один из них не равен нулю. Я думаю, что вы хотите, чтобы определить, какие строки не были обновлены первым запросом, предполагая, что некоторые иденты обновлены до Null. Я предполагаю, что некоторые данные в ID_1 \ ID_2 имеют значение NULL, так как столбцы acct всегда будут заполнены данными. Если мое предположение верно вы можете сделать следующее:

Изменить запрос:

create table #temp_table 
(
    s_acct char(8) null, 
    name varchar(50) null, 
    ident varchar(10) null 
) 

insert into #temp_table 
select distinct st.ship2, t.name, null 
from sales_table st, account_table t 
where st.bill2 = @acct 
and st.ship2 = t.acct 

update #temp_table 
set ident = COALESCE(lp.ID_1, lp.ID_2, 'BOTH LPS ARE NULL?') 
from lp_table lp 
where #temp_table.s_acct = lp.acct COLLATE Latin1_General_CS_AS 


select * from #temp_table 
where ident is not null 

И как в ответ M.Ali по его можно улучшить, чтобы удалить временную таблицу Useage и сделать это за один раз , Я включил это для полноты.

+0

в первом 'UPDATE' он должен только вставить' ID_1', поэтому для тех учетных записей, которые не были назначены 'ID_1', столбец' ident' по-прежнему является NULL, поэтому мой второй 'UPDATE' работает правильно. Третий «ОБНОВЛЕНИЕ» - это то место, где я запутался. – soundwave

Смежные вопросы