views:

1368

answers:

1

I have this sql:

UPDATE JOBMAKE SET WIP_STATUS='10sched1'
WHERE JBT_TYPE IN (SELECT JBT_TYPE FROM JOBVISIT WHERE JVST_ID = 21)
AND JOB_NUMBER IN (SELECT JOB_NUMBER FROM JOBVISIT WHERE JVST_ID = 21)

It works until I turn it into a parameterised query:

UPDATE JOBMAKE SET WIP_STATUS='10sched1'
WHERE JBT_TYPE IN (SELECT JBT_TYPE FROM JOBVISIT WHERE JVST_ID = @jvst_id)
AND JOB_NUMBER IN (SELECT JOB_NUMBER FROM JOBVISIT WHERE JVST_ID = @jvst_id)

Duplicated parameter names are not allowed. [  Parameter name = @jvst_id ]

I tried this (which i think would work in SQL SERVER 2005 - although I haven't tried it):

UPDATE JOBMAKE 
SET WIP_STATUS='10sched1' 
FROM JOBMAKE JM,JOBVISIT JV
WHERE  JM.JOB_NUMBER = JV.JOB_NUMBER
AND JM.JBT_TYPE = JV.JBT_TYPE 
AND JV.JVST_ID = 21
There was an error parsing the query. [ Token line number = 3,Token line offset = 1,Token in error = FROM ]

So, I can write dynamic sql instead of using parameters, or I can pass in 2 parameters with the same value, but does someone know how to do this a better way?

Colin

+2  A: 

Your second attempt doesn't work because, based on the Books On-Line entry for UPDATE, SQL CE does't allow a FROM clause in an update statement.

I don't have SQL Compact Edition to test it on, but this might work:

UPDATE JOBMAKE
SET WIP_STATUS = '10sched1'
WHERE EXISTS (SELECT 1
              FROM JOBVISIT AS JV
              WHERE JV.JBT_TYPE   = JOBMAKE.JBT_TYPE
              AND   JV.JOB_NUMBER = JOBMAKE.JOB_NUMBER
              AND   JV.JVST_ID    = @jvst_id
             )

It may be that you can alias JOBMAKE as JM to make the query slightly shorter.

EDIT

I'm not 100% sure of the limitations of SQL CE as they relate to the question raised in the comments (how to update a value in JOBMAKE using a value from JOBVISIT). Attempting to refer to the contents of the EXISTS clause in the outer query is unsupported in any SQL dialect I've come across, but there is another method you can try. This is untested but may work, since it looks like SQL CE supports correlated subqueries:

UPDATE JOBMAKE 
SET WIP_STATUS = (SELECT JV.RES_CODE 
                  FROM JOBVISIT AS JV 
                  WHERE JV.JBT_TYPE = JOBMAKE.JBT_TYPE 
                  AND   JV.JOB_NUMBER = JOBMAKE.JOB_NUMBER 
                  AND   JV.JVST_ID = 20
                 )

There is a limitation, however. This query will fail if more than one row in JOBVISIT is retuned for each row in JOBMAKE. If this doesn't work (or you cannot straightforwardly limit the inner query to a single row per outer row), it would be possible to carry out a row-by-row update using a cursor.

Ed Harper
That certainly works for my particular scenario. Thank-you.However, if I had wanted to update to a value from the JobVisit table, how would I do it?I tried (just as a test)UPDATE JOBMAKESET WIP_STATUS = JV.RES_CODEWHERE EXISTS (SELECT 1 FROM JOBVISIT AS JV WHERE JV.JBT_TYPE = JOBMAKE.JBT_TYPE AND JV.JOB_NUMBER = JOBMAKE.JOB_NUMBER AND JV.JVST_ID = 20)The column name is not valid. [ Node name (if any) = JV,Column name = RES_CODE ]
Colin
I get this error when I try that syntax: "There was an error parsing the query. [ Token line number = 2,Token line offset = 2,Token in error = SELECT ]"I believe that Sql CE does not support sub-queries that return scalar values.
Colin
In which case, I don't believe you can do this in a single query. You'd have to assign a value to a variable in one query, then use the variable to do the update in the second.
Ed Harper
Thanks Ed. You answered my question.
Colin