简体   繁体   English

SQL Server 2008: Select 然后更新语句

[英]SQL Server 2008: Select then update statement

I'm doing a INNER JOIN across 6 tables for a module for my application, basically it takes the prostaff an gets their name and email, and compares that to a list of job applicants.我正在为我的应用程序的一个模块跨 6 个表进行 INNER JOIN,基本上它需要 prostaff 获取他们的名字和 email,并将其与求职者列表进行比较。

On the mod_employmentAppJobs I need to set a column for each row selected to true.在 mod_employmentAppJobs 上,我需要为选择的每一行设置一列为真。 Basically this sets a flag that tells the sql not to select the column because we already sent an email on that user.基本上,这会设置一个标志,告诉 sql 不要 select 该列,因为我们已经向该用户发送了 email。 It's a bit field.这是一个位领域。

How do I set the emailSent field to true on a SQL statement?如何在 SQL 语句中将 emailSent 字段设置为 true? -- Coldfusion 8 is the Application server, just FYI.... -- 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'

You could store the result in a temporary table.您可以将结果存储在临时表中。 You can use the data in the temporary table, and still return it at the end.您可以使用临时表中的数据,最后仍然返回。 It's a lot of typing but pretty straightforward:打字很多,但非常简单:

-- 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

You have a couple of choices.你有几个选择。

1) Use a temp table and select data there first, update the mod_employmentAppJobs, and perform a select from the temp table to get your data retrieved. 1)首先使用临时表和 select 数据,更新 mod_employmentAppJobs,然后从临时表中执行 select 以检索您的数据。

So, it would look something like this.所以,它看起来像这样。

create a temp table创建临时表

CREATE TABLE #tmpTABLE 
(
  EmailAddress varchar(100),
  JobTitle varchar(50),
  JobTitleId bigint 
  ......
)

Insert into it插入其中

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'

Update the source table (I'd recommend an index on jobTitleId in the temp table for performance if applicable)更新源表(如果适用,我建议在临时表中对 jobTitleId 建立索引以提高性能)

UPDATE mod_employmentAddJobs
    SET EmailSent="true"
    FROM mod_employmentAppJobs b
      INNER JOIN #tmpTable tmp
    ON b.jobTitleID=tmp.jobTitleID

Get the actual data back to the app layer将实际数据返回到应用层

SELECT * FROM #tmpTable

For better taste, I recommend sprinkling with BEGIN TRAN...COMMIT...ROLLBACK and BEGIN TRY..END TRY BEGIN CATCH...END CATCH to taste and to business requirements.为了获得更好的口味,我建议使用 BEGIN TRAN...COMMIT...ROLLBACK 和 BEGIN TRY..END TRY BEGIN CATCH...END CATCH 来满足口味和业务需求。

Also, it's good manners to drop the temp table after you are done with it, even though SQL server will not take offense if you don't.此外,在您完成临时表后删除它是一种很好的方式,即使 SQL 服务器如果您不这样做也不会受到冒犯。

2) You can use the OUTPUT clause of the update statement. 2)可以使用更新语句的OUTPUT子句。

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'

OUTPUT inserted.* OUTPUT 已插入。*

This should get you the resultset right back to your app layer这应该让你的结果集回到你的应用层

If you need to update and then return the data then probably the best is to use a Stored Procedure, where you first query the data, update it and then return it.如果您需要更新然后返回数据,那么最好的方法可能是使用存储过程,您首先查询数据,更新它然后返回它。

Well, this is just an idea, not the best solution.嗯,这只是一个想法,不是最好的解决方案。
You could get data (for which bit is false) in a DataReader and then execute a Command setting bit to true for ids contained in Dataset.您可以在 DataReader 中获取数据(该位为假),然后对 Dataset 中包含的 id 执行命令设置位为真。
Dataset returns data you need...数据集返回您需要的数据...

I just tacked a on the end and it worked:我只是在最后加上了一个,它起作用了:

    UPDATE mod_employmentAppJobs
    SET emailSent = 'True'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM