Question

I have the following relation in sql server database:

enter image description here

Assume I want to do some modifications in the relation. I want to remove the CPU_TYPE table and add one column 'cpu' in the computer table.

Now I want to use the 'with' clause in sql server to query the data joined from the two tables and do the update statement to update the computer table.

This sql server query:

SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId, 
CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
FROM COMPUTER LEFT OUTER JOIN
CPU_TYPE ON COMPUTER.cpuId = CPU_TYPE.cpuId

And the results as follows:

enter image description here

Now I will create a dataset using the 'with' clause as follows:

with ds as
(
SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId, 
CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
FROM COMPUTER LEFT OUTER JOIN
CPU_TYPE ON COMPUTER.cpuId = CPU_TYPE.cpuId
)
update ds set cpu = name +', '+ cpuSpeed;

And the results as follws:

enter image description here

The query is executed successfully but the problem is that the COMPUTER table has not changed! How to solve this problem?

Était-ce utile?

La solution

Your code is fine. Your data is off. CPUSpeed is NULL so the result of the concatenation will always be NULL. So, use coalesce():

with ds as (
      SELECT COMPUTER.compID, COMPUTER.serialNo, COMPUTER.cpuId, 
             CPU_TYPE.name, CPU_TYPE.cpuSpeed, COMPUTER.cpu
      FROM COMPUTER LEFT OUTER JOIN
           CPU_TYPE
           ON COMPUTER.cpuId = CPU_TYPE.cpuId
     )
update ds
     set cpu = name +', '+ coalesce(cpuSpeed, '');

Autres conseils

As I am sure many will note here in their answers, you do not have to use a Common Table Expression to accomplish this UPDATE.

That said, however, you could (in case you are looking to practice your CTE skills):

WITH cte AS
(
    SELECT c1.compID, c2.name, c2.cpuSpeed
    FROM [COMPUTER] AS c1
    LEFT OUTER JOIN [CPU_TYPE] AS c2
        ON ( comp.cpuId = c2.cpuId )
)
UPDATE [COMPUTER]
SET cpu = cte.name + ', ' + cte.cpuSpeed
FROM [COMPUTER] AS comp
INNER JOIN cte ON ( comp.compId = cte.compId )

If you wanted to filter your CTEs result then you could add a WHERE clause to your CTE like:

WHERE c1.cpuId IS NOT NULL

Or anything else for that matter.

Update

If you do, in fact, have NULL data in your cpuSpeed column, then you may want to consider the following SET statement instead of the SET listed above:

SET cpu = cte.name + Coalesce(', ' + cte.cpuSpeed, '')

...or alternatively:

SET cpu = cte.name + IsNull(', ' + cte.cpuSpeed, '')

This way if cpuSpeed is NULL, then you still have the data from the name column without the comma (",") appended at the end; if name is also NULL (or NULL instead is cpuSpeed), then cpu will be set to NULL.

Remember, you could always add an even more protective filter to your CTE, like:

WHERE c1.cpuId IS NOT NULL AND c2.name IS NOT NULL

Naturally, you should adjust the SQL to suit your specific requirements.

I hope this helps. Good luck!

Just try this instead of using a CTE.

UPDATE COMPUTER 
SET cpu = name + ', ' + cpuSpeed
FROM COMPUTER C1 LEFT OUTER JOIN
CPU_TYPE ON C1.cpuId = CPU_TYPE.cpuId
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top