Dynamic UPDATE statement - sql

I want to create a dynamic update query where I need to set a certain value in a column. But the column name needs to be SELECTed from another table.
I have already the following query:
UPDATE core.TableRes
SET (
SELECT Code FROM core.TableFields
INNER JOIN core.TableXTableFields ON TableXTableFields.FieldID = TableFields.FieldID
INNER JOIN core.TableResRefLinks ON TableResRefLinks.ExtraFieldID = TableXTableFields.ExtraFieldID
WHERE TableResRefLinks.TableResRefLinksID = RefLinks.TableResRefLinksID)
= (
SELECT Value FROM core.TableResRefLinks WHERE TableResRefLinksID = RefLinks.TableResRefLinksID)
FROM core.TableRes
INNER JOIN core.TableResRefLinks RefLinks ON RefLinks.ResourceID = TableRes.ResourceID
INNER JOIN core.TableXTableFields ON TableXTableFields.ExtraFieldID = RefLinks.ExtraFieldID
INNER JOIN core.TableFields ON TableFields.FieldID = TableXTableFields.FieldID
WHERE (EndDate IS NULL OR EndDate > GETDATE()) AND
(
SELECT Code FROM core.TableFields
INNER JOIN core.TableXTableFields ON TableXTableFields.FieldID = TableFields.FieldID
INNER JOIN core.TableResRefLinks ON TableResRefLinks.ExtraFieldID = TableXTableFields.ExtraFieldID
WHERE TableResRefLinks.TableResRefLinksID = RefLinks.TableResRefLinksID)
<>
(
SELECT Value FROM core.TableResRefLinks
WHERE TableResRefLinksID = RefLinks.TableResRefLinksID)
It gives me the following errors:
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '('.
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '='.
Msg 156, Level 15, State 1, Line 5
Incorrect syntax near the keyword 'FROM'.
Msg 102, Level 15, State 1, Line 14
Incorrect syntax near '<'.
Is there a way to solve this? If I change the complete UPDATE and SET statements and replace them with a SELECT *, I get results.
EDIT
Here are the datatypes
TableFields.Code => nvarchar(100)
TableResRefLinks.Value => sql_variant
And the datatypes of the columns that have as column name TableFields.Code are set as sql_variant

You can't solve this using plain SQL. You would need some kind of scripting to build your statement. For example postgresql has a scripting language called "pgpsql" which allows building dynamic SQL statements. But this clearly depends on the underlying RDBMS.
By the way: this works with SELECT as you are doing simple sub-select.

Related

sybase script don't understand trouble

I 'm not a regular of Sybase ASE.
Tring to make a script to add line into a tempory table.
sybase version 12.5.4
BEGIN
declare and init variable
--boucle
select * into #parTemp from Parution where 1=2
WHILE #dateCourante <= #dateFin
BEGIN
select #dpart1=datepart(mm,#dateCourante)
select #dpart2=datepart(dd,#dateCourante)
select #dpart3=datepart(dw,#dateCourante)
--si on est pas le 1er mai
if #dpart1 <> 5 AND #dpart2 <> 1
begin
--id parution
select #idPar = #idPar + 1
select #idParChaine = convert(varchar(10),#idPar)
--num parution
select #numPar = #numPar + 1
select #numParChaine = convert(varchar(20),#numPar)
--prix du jour courant
if datepart(dw,#dateCourante)=6
select #prixCourant = #prixVen
else
if datepart(dw,#dateCourante)=1
select #prixCourant = #prixDim
else
select #prixCourant = #prix
end
end
insert into #parTemp values (#idParChaine,#dateCourante,#numParChaine,#nbPagination,#prixCourant,#poids,#parCompt,#parOJD,#resVal)
end
select #dateCourante = dateadd(dd,1,#dateCourante)
END
END
Errors i get :
Error code 156, SQL state ZZZZZ: Incorrect syntax near the keyword 'WHILE'.
Error code 156, SQL state ZZZZZ: Incorrect syntax near the keyword 'end.
Error code 156, SQL state ZZZZZ: Incorrect syntax near the keyword 'End'.
i really don't understand, thank for help.
Pierre

The multi-part identifier could not be bound error with update statement and where exists clause

My query is as shown below . I am getting error as
Msg 4104, Level 16, State 1, Procedure USP_Group11HtmlFileDetails,
Line 71
The multi-part identifier "t_FI.Fullimage" could not be bound.
Msg 4104, Level 16, State 1, Procedure USP_Group11HtmlFileDetails,
Line 71
The multi-part identifier "t_FI.Caption" could not be bound.
#tblGroup11HtmlFileImages is table variable which is of type exactly similar to ta
Query
UPDATE FI
SET FI.Fullimage = t_FI.Fullimage,
FI.Caption = t_FI.Caption
FROM tblGroup11HtmlFileImages FI
WHERE EXISTS (SELECT *
FROM #tblGroup11HtmlFileImages t_FI
WHERE t_FI.[FileName] = FI.[FileName]
AND t_FI.Thumbnail = FI.Thumbnail)
The exists operator only checks for existence of a value, no value is actually retrieved from the Exists operator.
You need to join these two tables something like....
UPDATE FI
SET FI.Fullimage = t_FI.Fullimage
, FI.Caption = t_FI.Caption
FROM tblGroup11HtmlFileImages FI
INNER JOIN #tblGroup11HtmlFileImages t_FI
ON t_FI.[FileName] = FI.[FileName]
AND t_FI.Thumbnail = FI.Thumbnail

SQL query working on SQL Server 2014 but not on 2008 R2

the following query works just fine on SQL Server 2014, but returns following error on SQL Server 2008:
Mens. 102, Nivel 15, Estado 1, Línea 1
Incorrect syntax near '='.
Mens. 156, Nivel 15, Estado 1, Línea 4
Incorrect syntax near the keyword 'AS'.
Mens. 156, Nivel 15, Estado 1, Línea 7
Incorrect syntax near the keyword 'AS'.
This is the query (a bit long, sorry):
SELECT per_agrup.COEMPRESA AS 'Empresa',
per_agrup.DCCENTROS AS 'Centre',
per_agrup.DCDIVISIONES AS 'Divisió',
per_agrup.DCGRUPPROF AS 'Grup professional',
per_agrup.DCUNIPROD AS 'Direcció/Àrea',
per_agrup.DCPUESTOTRABAJO AS 'Lloc de treball',
per_agrup.DCCATEGORIA AS 'Categoria',
per_agrup.DCINCIDENCIA AS 'Motiu',
Sum(IIf(per_agrup.COMPERSONAL=1
And per_agrup.COCOBERTURA Is Not Null,
IIf(per_cober_agrup.COCOBERTURA Is Not Null And per_cober_agrup.COMPERSONAL=1,Round(per_cober_agrup.SumaDeHORAS/60.00,2),
IIf(per_cober_agrup.COCOBERTURA Is Null,Round(per_agrup.SumaDeHORAS/60.00,2),0)),Round(per_agrup.SumaDeHORAS/60.00,2))) AS HORES
FROM ( SELECT TENPLANING_PER.COEMPRESA,
TENPLANING_PER.COIDENNUMERO,
TENPLANING_PER.FECHAJORNADA,
TENPLANING_PER.COPUESTOTRABAJO,
TENPLANING_PER.COTIPOMOV,
TENPLANITIPOINCIDEN.DCINCIDENCIA,
TENPLANITIPOINCIDEN.COMPERSONAL,
TENPLANING_PER.COCOBERTURA,
DCPUESTOTRABAJO,
DCDIVISIONES,
DCGRUPPROF,
DCUNIPROD,
DCCATEGORIA,
DCCENTROS,
Sum(TENPLANING_PER.HORAS) AS SumaDeHORAS
FROM TENPLANITIPOINCIDEN
INNER JOIN TENPLANING_PER ON (TENPLANITIPOINCIDEN.COINCIDENCIA = TENPLANING_PER.COTIPOMOV)
AND (TENPLANITIPOINCIDEN.COEMPRESA = TENPLANING_PER.COEMPRESA)
JOIN TPUESTOTRABAJO ON TPUESTOTRABAJO.COEMPRESA=TENPLANING_PER.COEMPRESA
AND TENPLANING_PER.COPUESTOTRABAJO=TPUESTOTRABAJO.COPUESTOTRABAJO
JOIN TUNIPROD ON TENPLANING_PER.COEMPRESA=TUNIPROD.COEMPRESA
AND TUNIPROD.COUNIPROD=TPUESTOTRABAJO.COPTUNIDPRO
JOIN TDIVISIONES ON TDIVISIONES.COEMPRESA=TUNIPROD.COEMPRESA
AND TDIVISIONES.CODIVISIONES=TUNIPROD.CODIVISION
JOIN TCATEGORIAS ON TCATEGORIAS.COEMPRESA=TPUESTOTRABAJO.COEMPRESA
AND TCATEGORIAS.COCATEGORIA=TPUESTOTRABAJO.COPTCATEGORIA
JOIN TGRUPPROF ON TENPLANING_PER.COEMPRESA=TGRUPPROF.COEMPRESA
AND TGRUPPROF.COGRUPPROF=TCATEGORIAS.COGRUPPROF
JOIN TCENTROS ON TUNIPROD.COEMPRESA=TCENTROS.COEMPRESA
AND TUNIPROD.COCENTRO=TCENTROS.COCENTROS
GROUP BY TENPLANING_PER.COEMPRESA,
TENPLANING_PER.COIDENNUMERO,
TENPLANING_PER.FECHAJORNADA,
TENPLANING_PER.COPUESTOTRABAJO,
TENPLANING_PER.COTIPOMOV,
TENPLANITIPOINCIDEN.DCINCIDENCIA,
TENPLANITIPOINCIDEN.COMPERSONAL,
TENPLANING_PER.COCOBERTURA,
DCPUESTOTRABAJO,
DCDIVISIONES,
DCGRUPPROF,
DCUNIPROD,
DCCATEGORIA,
DCCENTROS ) AS per_agrup
LEFT JOIN ( SELECT TENPLANING_PER_COBER.COEMPRESA,
TENPLANING_PER_COBER.COIDENNUMERO,
TENPLANING_PER_COBER.COCOBERTURA,
TENPLANING_PER_COBER.FECHAJORNADA,
TENPLANING_PER_COBER.COTIPOMOV,
TENPLANITIPOINCIDEN.DCINCIDENCIA,
TENPLANITIPOINCIDEN.COMPERSONAL,
TENPLANING_PER_COBER.COPUESTOTRABAJO,
Sum(TENPLANING_PER_COBER.HORAS) AS SumaDeHORAS
FROM TENPLANITIPOINCIDEN
INNER JOIN TENPLANING_PER_COBER ON (TENPLANITIPOINCIDEN.COINCIDENCIA = TENPLANING_PER_COBER.COTIPOMOV) AND (TENPLANITIPOINCIDEN.COEMPRESA = TENPLANING_PER_COBER.COEMPRESA)
GROUP BY TENPLANING_PER_COBER.COEMPRESA,
TENPLANING_PER_COBER.COIDENNUMERO,
TENPLANING_PER_COBER.COCOBERTURA,
TENPLANING_PER_COBER.FECHAJORNADA,
TENPLANING_PER_COBER.COTIPOMOV,
TENPLANITIPOINCIDEN.DCINCIDENCIA,
TENPLANITIPOINCIDEN.COMPERSONAL,
TENPLANING_PER_COBER.COPUESTOTRABAJO ) AS per_cober_agrup ON per_agrup.COEMPRESA = per_cober_agrup.COEMPRESA
AND per_agrup.COIDENNUMERO = per_cober_agrup.COIDENNUMERO
AND per_agrup.FECHAJORNADA = per_cober_agrup.FECHAJORNADA
AND per_agrup.COCOBERTURA = per_cober_agrup.COCOBERTURA
GROUP BY per_agrup.COEMPRESA,
per_agrup.DCCENTROS,
per_agrup.DCDIVISIONES,
per_agrup.DCGRUPPROF,
per_agrup.DCUNIPROD,
per_agrup.COTIPOMOV,
per_agrup.DCINCIDENCIA,
per_agrup.DCPUESTOTRABAJO,
per_agrup.DCCATEGORIA,
per_agrup.COMPERSONAL,
Year(per_agrup.FECHAJORNADA),
Month(per_agrup.FECHAJORNADA)
HAVING ((per_agrup.COEMPRESA='1')
AND ((per_agrup.COTIPOMOV)=6
OR (per_agrup.COTIPOMOV)=48
OR (per_agrup.COTIPOMOV)=85
OR (per_agrup.COTIPOMOV)=71
OR (per_agrup.COTIPOMOV)=61
OR (per_agrup.COTIPOMOV)=5
OR (per_agrup.COTIPOMOV)=9
OR (per_agrup.COTIPOMOV)=94
OR (per_agrup.COTIPOMOV)=11
OR (per_agrup.COTIPOMOV)=111
OR (per_agrup.COTIPOMOV)=22
OR (per_agrup.COTIPOMOV)=7)
AND ((Year(per_agrup.FECHAJORNADA))=2015)
AND ((Month(per_agrup.FECHAJORNADA))=1))
ORDER BY per_agrup.COEMPRESA,
per_agrup.DCCENTROS,
per_agrup.DCDIVISIONES,
per_agrup.DCGRUPPROF,
per_agrup.DCUNIPROD,
per_agrup.DCPUESTOTRABAJO,
per_agrup.DCCATEGORIA,
per_agrup.DCINCIDENCIA
I have noticed that removing this last column query works fine
Sum(IIf(per_agrup.COMPERSONAL=1 And per_agrup.COCOBERTURA Is Not Null,IIf(per_cober_agrup.COCOBERTURA Is Not Null And per_cober_agrup.COMPERSONAL=1,Round(per_cober_agrup.SumaDeHORAS/60.00,2),IIf(per_cober_agrup.COCOBERTURA Is Null,Round(per_agrup.SumaDeHORAS/60.00,2),0)),Round(per_agrup.SumaDeHORAS/60.00,2))) AS HORES
What is wrong with this last column in SQL Server 2008?
Thank you and excuse me for my bad english.
Replacing IIF's with CASE statment solved the problem.
Thanks to #Lamak and #chipmunkofdoom2

SQL Help - If Then Else

I need the help of someone who understands SQL better than I do...
I am trying to make a single SP call that uses the IF THEN ELSE but keep getting three "the multi-part identifier could not be bound" messages.
Pages can be sponsored by a Business or a Group.
In the advertEntityType field I have a "B" or a "G" for business or group.
In the advertEntityID field I have the businessID or groupID.
SELECT
Advertisements.advertEntityType
,Advertisements.advertEntityID
FROM Advertisements
WHERE Advertisements.advertPageName = #pageName
IF (Advertisements.advertEntityType = 'G')
SELECT
Group.groupID
,Group.groupName
,Group.groupPhone
,Group.groupWebsite
,Group.groupLogoName
FROM Group
WHERE Group.groupID = Advertisements.advertEntityID
ELSE
SELECT
Business.businessID
,Business.businessName
,Business.businessWorkPhone
,Business.businessWebsite
,Business.businessLogoName
FROM Business
WHERE Business.businessID = Advertisements.advertEntityID
When I try to execute I get these messages which I cannot seem to get my head around...
Msg 4104, Level 16, State 1, Procedure Sponsor_s01, Line 36
The multi-part identifier "Advertisements.advertEntityType" could not be bound.
Msg 4104, Level 16, State 1, Procedure Sponsor_s01, Line 46
The multi-part identifier "Advertisements.advertEntityID" could not be bound.
Msg 4104, Level 16, State 1, Procedure Sponsor_s01, Line 58
The multi-part identifier "Advertisements.advertEntityID" could not be bound.
Advertisements.advertEntityType is a table name and column name. You need to assign these values to local variables if you want to use them in if statements. If I understand correctly you want to evaluate based on the condition in the first select statement. In this case you should use such query:
DECLARE #entityType int --assuming the type of Advertisements.advertEntityType is int
DECLARE #advertEntityID int --assuming the type of Advertisements.advertEntityID is int
SELECT
#entityType = Advertisements.advertEntityType,
#advertEntityID = Advertisements.advertEntityID
FROM Advertisements
WHERE Advertisements.advertPageName = #pageName
IF (#entityType = 'G')
SELECT
Group.groupID
,Group.groupName
,Group.groupPhone
,Group.groupWebsite
,Group.groupLogoName
FROM Group
WHERE Group.groupID = #advertEntityID
ELSE
SELECT
Business.businessID
,Business.businessName
,Business.businessWorkPhone
,Business.businessWebsite
,Business.businessLogoName
FROM Business
WHERE Business.businessID = #advertEntityID

Change date difference with CASE calculation

I have a holding table for data, before adding to a final table in my database.
Within that table is a datediff calculation, which returns the number of days in a month.
However, this is baased on projects and what I need to do is look up the Project ID in another table, to see whether the TimeID (Year/Month) is equal to either the Start- or End-Date of the project.
When it matches either, it needs to change the number of days for that month to either Month-Start to Project-Finish (if it's the end month) or Project-Start to Month-End (if it's the start month).
I've tried to do this with the following script but I get the errors:
*** This bit is sorted, please see below ***
Msg 156, Level 15, State 1, Line 15
Incorrect syntax near the keyword 'FROM'.
Msg 102, Level 15, State 1, Line 23
Incorrect syntax near 'A'.
*** This bit is sorted, please see below ***
* EDIT *
Thanks to Anton, I've added the required END to my CASE statement, but I now get a different set of errors (probably down to my syntax):
Msg 207, Level 16, State 1, Line 23
Invalid column name 'TimeID'.
Msg 207, Level 16, State 1, Line 20
Invalid column name 'TimeID'.
Msg 207, Level 16, State 1, Line 26
Invalid column name 'ID'.
Msg 207, Level 16, State 1, Line 28
Invalid column name 'ID'.
Please help if you can.
The script is:
UPDATE FAC
SET FAC.[SignedData] =
CASE
WHEN FAC.[TIMEID] = A.[Start_TimeID] THEN
CASE
WHEN pd.[Start_Date] >= GETDATE() THEN datediff(day,pd.[Start_Date],pt.[Period_End])
WHEN pd.[Start_Date] < GETDATE() THEN datediff(day,GETDATE(),pt.[Period_End])
END
WHEN FAC.[TIMEID] = A.[End_TimeID] THEN
CASE
WHEN pd.[End_Date] >= GETDATE() THEN datediff(day,getdate(),pd.[End_Date])
WHEN pd.[End_Date] < GETDATE() THEN '0'
END
END
FROM Temp_Fac2Programme FAC
JOIN
(
SELECT
pd.[TimeID], pd.[Start_TimeID], pd.[End_TimeID], pt.[Period_Start], pt.[Period_End]
FROM ProjectDates pd
JOIN ProjectTimeID pt
on pd.[TimeID] = pt.[TimeID]
) A
ON A.[ID] = FAC.[Project]
Where A.[ID] = FAC.[Project]
GO
NB - SIGNEDDATA is the number of days in the month.
* Example Data *
Temp_Fac2Programme (FAC) contains:
ACCOUNT CATEGORY DATASRC PROFITCENTRE PROJECT RPTCURRENCY TIMEID SIGNEDDATA SOURCE
REMAIN_DAYS_FLAG ACTUAL DS_FLAGS B9059 AAA_7915_BBOY LC 20130100 34.0000000000 0
ProjectDates (pd) contains:
PROJECT_ID START_TIMEID END_TIMEID START_DATE END_DATE TOTAL_DAYS
PAG_5244_CASH 20110400 20120300 2011-04-01 2012-03-31 365
ProjectTimeID (pt) contains:
TIMEID PERIOD_START PERIOD_END DAYS_IN_PERIOD PCMONTHSTAT
20140600 2014-05-31 2014-06-27 27 F
As of the current (edited) version, it's basically what error messages say:
You use pd.[TimeID] in two places, but there is no TimeID column in ProjectDates (for now, I have no idea what you meant here).
Your subquery (aliased to A) has no ID column. The likely fix is adding pd.[Project_ID] as ID into the subquery's list of selected fields.