#sql #sql-server-2008
#sql #sql-server-2008
Вопрос:
Я выполняю ВНУТРЕННЕЕ объединение между 6 таблицами для модуля для моего приложения, в основном это берет prostaff, получает их имя и адрес электронной почты и сравнивает это со списком кандидатов на работу.
В mod_employmentAppJobs мне нужно присвоить столбцу для каждой выбранной строки значение true. По сути, это устанавливает флаг, который сообщает sql не выбирать столбец, потому что мы уже отправили электронное письмо этому пользователю. Это битовое поле.
Как мне установить для поля emailSent значение true в инструкции SQL? — К вашему сведению, Coldfusion 8 — это сервер приложений….
SELECT *
FROM pro_Profile p
INNER JOIN pro_Email e ON p.profileID = e.profileID
INNER JOIN mod_userStatus m ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a ON p.profileID = a.departmentID
<!--- Join Job titles to the jobs --->
INNER JOIN mod_employmentAppJobs b ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
Комментарии:
1. Если это битовое поле, я думаю, вы могли бы установить значение 1 (для true) или 0 (для false).
2. Также вот в чем дело, его необходимо обновить, но ему необходимо вернуть данные после SQL.
3. Ее легче читать, если установлено значение false, и она работает в любом случае.
4. Извините, я не понимаю, что вам нужно (это моя вина, мой английский действительно плохой). Вам нужно прочитать данные, для которых битовое поле равно false, а затем установить для этого поля значение true для всех возвращенных записей?
5. Да, Марко. Мне нужно получить данные, затем установите для поля emailSent значение false.
Ответ №1:
У вас есть несколько вариантов.
1) Используйте временную таблицу и сначала выберите данные там, обновите mod_employmentAppJobs и выполните выбор из временной таблицы, чтобы получить ваши данные.
Итак, это будет выглядеть примерно так.
создайте временную таблицу
CREATE TABLE #tmpTABLE
(
EmailAddress varchar(100),
JobTitle varchar(50),
JobTitleId bigint
......
)
Вставьте в нее
INSERT INTO #tmpTable
SELECT EmailAddress,JobTitle, ........
FROM pro_Profile p
INNER JOIN pro_Email e
ON p.profileID = e.profileID
INNER JOIN mod_userStatus m
ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a
ON p.profileID = a.departmentID
INNER JOIN mod_employmentAppJobs b
<!--- Join Job titles to the jobs --->
ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c
ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
Обновите исходную таблицу (я бы рекомендовал индекс jobTitleId во временной таблице для повышения производительности, если это применимо)
UPDATE mod_employmentAddJobs
SET EmailSent="true"
FROM mod_employmentAppJobs b
INNER JOIN #tmpTable tmp
ON b.jobTitleID=tmp.jobTitleID
Верните фактические данные обратно на уровень приложения
SELECT * FROM #tmpTable
Для лучшего вкуса я рекомендую добавить BEGIN TRAN…ЗАФИКСИРУЙТЕ…ВЫПОЛНИТЕ ОТКАТ и НАЧНИТЕ TRY ..END TRY НАЧНИТЕ CATCH…ЗАВЕРШИТЕ по вкусу и в соответствии с требованиями бизнеса.
Кроме того, рекомендуется удалять временную таблицу после того, как вы закончите с ней, хотя SQL server не обидится, если вы этого не сделаете.
2) Вы можете использовать предложение OUTPUT инструкции update.
UPDATE mod_employmentAddJobs
SET EmailSent="true"
FROM pro_Profile p
INNER JOIN pro_Email e
ON p.profileID = e.profileID
INNER JOIN mod_userStatus m
ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a
ON p.profileID = a.departmentID
INNER JOIN mod_employmentAppJobs b
<!--- Join Job titles to the jobs --->
ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c
ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
Вставлен вывод.*
Это должно вернуть вам результирующий набор обратно на уровень вашего приложения
Ответ №2:
Вы могли бы сохранить результат во временной таблице. Вы можете использовать данные во временной таблице и по-прежнему возвращать их в конце. Это много ввода, но довольно просто:
-- Select data into temporary table
declare @result table (jobTitleID int, ...)
INSERT @result
(jobTitleID, ...)
SELECT jobTitleID
FROM pro_Profile p
...
-- Update unreadMail flag
update mod_employmentAppJobs
set unreadMail = 'False'
where jobTitleID in (select jobTitleId from @result)
-- Return result to application
select jobTitleId, ...
from @result
Ответ №3:
Если вам нужно обновить, а затем вернуть данные, то, вероятно, лучше всего использовать хранимую процедуру, где вы сначала запрашиваете данные, обновляете их, а затем возвращаете.
Ответ №4:
Ну, это всего лишь идея, а не лучшее решение.
Вы могли бы получить данные (для которых бит равен false) в DataReader, а затем выполнить команду, устанавливающую бит в значение true для идентификаторов, содержащихся в Dataset.
Dataset возвращает необходимые данные…
Ответ №5:
Я просто добавил a в конец, и это сработало:
UPDATE mod_employmentAppJobs
SET emailSent = 'True'
Комментарии:
1. Но что произойдет, если между запуском инструкции SELECT и выполнением инструкции UPDATE есть вставка? Будут записи, помеченные как TRUE, если они никогда не были возвращены из инструкции SELECT.