开发者

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.

On the mod_employmentAppJobs I need to set a column for each row selected to true. Basically this sets a flag that tells 开发者_开发百科the sql not to select the column because we already sent an email on that user. It's a bit field.

How do I set the emailSent field to true on a SQL statement? -- Coldfusion 8 is the Application server, just FYI....

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

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)

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.

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.

2) You can use the OUTPUT clause of the update statement.

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

This should get you the resultset right back to your app layer


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


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.
Dataset returns data you need...


I just tacked a on the end and it worked:

    UPDATE mod_employmentAppJobs
    SET emailSent = 'True'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜