Update query with variable - sql

Is it possible to update a variable with a concatenation of variables(columns of VARCHARS2)?
UPDATE ARTICLE
SET DESCRIPTION = (CPV_DESCRIPTION + '/' LEVEL1_DESCRIPTION + LEVEL2_DESCRIPTION+LEVEL3_DESCRIPTION)
WHERE ID_ARTICULO = 209;
UPDATE ARTICLE
SET DESCRIPTION = concat(CPV_DESCRIPTION,'/',LEVEL1_DESCRIPTION,' ',LEVEL2_DESCRIPTION' 'LEVEL3_DESCRIPTION)
WHERE ID_ARTICULO = 209;
Both cases it gives me an error.

As mentioned by #a_horse... concat() function only takes 2 parameters. When you specify more that 2 parameters to be concated, you need to use || operator. Also + is a logical operator in Oracle unlike its used in Java for concatenation. Try this:
UPDATE ARTICLE
SET DESCRIPTION = CPV_DESCRIPTION
|| '/'
||LEVEL1_DESCRIPTION
||' '
||LEVEL2_DESCRIPTION
||' '
||LEVEL3_DESCRIPTION
WHERE ID_ARTICULO = 209;

Related

Append A Value To The Existing Value In SQL, facing error

I have a table in which there is a column name associated_ids with datatype as varchar2(4000). It contains a value and i need to append the new value with existing value. Using below update query:
update ncl_getafix.service_graph
set Associated_ids = Associated_ids + ',' + '95d4980b-d12c-4854-97c6-bd9854f8f003'
where SERVICE_ID='075d7a58-7fad-4e1d-9822-83a2fa1a0d05';
I am getting below error:
Error starting at line : 5 in command - update
ncl_getafix.service_graph set
Associated_ids=Associated_ids+','+'95d4980b-d12c-4854-97c6-bd9854f8f003'
where SERVICE_ID='075d7a58-7fad-4e1d-9822-83a2fa1a0d05'
Error report - ORA-01722: invalid number.
Can anyone help to debug this.
You need to use concat operator || not + as follows:
update ncl_getafix.service_graph
set Associated_ids = Associated_ids || ',' || '95d4980b-d12c-4854-97c6-bd9854f8f003'
where SERVICE_ID='075d7a58-7fad-4e1d-9822-83a2fa1a0d05';
i found the answer.
Use || symbol instead of + in query

SQL Date Query using parameters - Delphi

I have an SQL Query (MS Access), and I want to add the Date() function into a parameter, however I get the error: [ODBC Microsoft Access Driver]Data type mismatch in criteria expression.
Here is the code:
Qry.SQL.Text := 'SELECT Bookings.Date, Bookings.WeekDay, Bookings.Shift, Bookings.Start, Bookings.Finish,'
+ ' Bookings.DateFinish, Wards.WardName'
+ ' FROM Bookings'
+ ' INNER JOIN Wards ON Bookings.WardNo = Wards.WardNo'
+ ' WHERE (Bookings.NurseNo=:nurseID) AND (Bookings.Date BETWEEN :dateA AND :dateB)'
+ ' ORDER BY Bookings.Date ASC;';
Qry.Params.ParamByName('dateA').Value := 'Date()';
Qry.Params.ParamByName('dateB').Value := 'Date()+6';
I've also tried Qry.Params.ParamByName('dateA').AsString := 'Date()'; but no luck with that, is there a correct way to do this, or would it actually have to be in the query and not parameterised? The reason I want to do it like this, is I will have multiple different queries based on which button is pressed, but the only thing changing is those parameterised dates.
A parameter can't be a function, it has to be a value. You are assigning strings as those values, and those strings do not represent valid dates. That is why you are getting a mismatch error.
You can use Delphi Date() function, and pass the returned TDate as a parameter value:
Qry.Params.ParamByName('dateA').Value := Date();
Qry.Params.ParamByName('dateB').Value := Date()+6;
Or, you can use Access's Date() function in the SQL itself:
Qry.SQL.Text := 'SELECT Bookings.Date, Bookings.WeekDay, Bookings.Shift, Bookings.Start, Bookings.Finish,'
+ ' Bookings.DateFinish, Wards.WardName'
+ ' FROM Bookings'
+ ' INNER JOIN Wards ON Bookings.WardNo = Wards.WardNo'
+ ' WHERE (Bookings.NurseNo=:nurseID) AND (Bookings.Date BETWEEN Date() AND Date() + 6)'
+ ' ORDER BY Bookings.Date ASC;';

Combining strings in DB2 Stored Procedure

I was wondering how to combine Varchar variables in a stored procedure. I want to combine email addresses into a single variable based of access level. I have tried doing a few things in my if statement.
For example I have tried both:
v_m1_email = Concat(v_m1_email, ' , ' , v_email)
and
v_m1_email = v_m1_email || ' , ' || v_email
My code:
CREATE PROCEDURE ALERTEMAIL (OUT p_m1_email VARCHAR(300),
OUT p_m2_email VARCHAR(300),
OUT p_m3_email VARCHAR(300),
OUT p_m4_email VARCHAR(300))
DYNAMIC RESULT SETS 1
P1: BEGIN
DECLARE v_email VARCHAR(50);
DECLARE v_access CHAR(5);
DECLARE v_m1_email VARCHAR(300);
DECLARE v_m2_email VARCHAR(300);
DECLARE v_m3_email VARCHAR(300);
DECLARE v_m4_email VARCHAR(300);
DECLARE SQLSTATE CHAR(5);
DECLARE cursor1 CURSOR WITH RETURN for
SELECT EMAIL,JOB_ID FROM PERSONNEL;
OPEN cursor1;
FETCH cursor1 INTO v_email, v_access;
WHILE (SQLSTATE = '00000') DO
IF v_access = 'Man1' THEN
SET v_m1_email = v_m1_email + ' , ' + v_email;
ELSEIF v_access = 'Man2' THEN
SET v_m2_email = v_m2_email + ' , ' + v_email;
ELSEIF v_access = 'Man3' THEN
SET v_m3_email = v_m3_email + ' , ' + v_email;
ELSEIF v_access = 'Man4' THEN
SET v_m4_email = v_m4_email + ' , ' + v_email;
END IF;
FETCH cursor1 INTO v_email, v_access;
END WHILE;
SET p_m1_email = v_m1_email;
SET p_m2_email = v_m2_email;
SET p_m3_email = v_m3_email;
SET p_m4_email = v_m4_email;
END P1
With regard to the first of what already had been tried from the OP, just as #I_am_Batman on 23-Apr-2016 already noted, the syntax for the CONCAT scalar >>-CONCAT--(--expression1--,--expression2--)------>< is limited to just the two arguments, so the expression coded as Concat(v_m1_email, ' , ' , v_email) would fail, presumably with a sqlcode=-170 suggesting something like "Number of arguments for function CONCAT not valid."
Which variant of DB2 was not noted [not in tag nor by comment in the OP], but I offer this link to some doc DB2 for Linux UNIX and Windows 9.7.0->Database fundamentals->SQL->Functions->Scalar functions->CONCAT
However there is nothing conspicuously incorrect with the second of what already had been tried from the OP; i.e. assuming the assignment and expression shown, had been coded just as shown in the body of the CREATE PROCEDURE, with a preceding SET and a trailing ;. In that case, the statement SET v_m1_email = v_m1_email || ' , ' || v_email; should have been able to pass both syntax-checking and data-type\validity-checking. Whereas what is shown in the OP as SET v_m1_email = v_m1_email + ' , ' + v_email; is not valid except when the values of both variables always would be valid string-representations of numbers; that is because the + operator is a numeric-operator rather than the [conspicuously as-desired] string-operator used to effect concatenation [i.e. for "combining strings"].
[ed: 22-Aug-2016] I forgot there was a constant\literal ' , ' in the above expression, so that string-literal also would have to evaluate as a numeric to allow that expression with the + as addition-operator to function at run-time. But of course, that literal could never be interpreted as a numeric; so while the expression could be treated as valid for compile-time [with implicit cast in effect and data-checking not examining the literal value], that expression never would be capable of being evaluated at run-time.
Therefore, if the || operator was properly coded [as seems so, given what was claimed to have been "tried"], yet did not effect what was desired, then the OP would need to be updated to state exactly what was the problem. For example, perhaps there was an error in compile\CREATE of the routine, or perhaps a run-time error for which the effect of the concatenation was perhaps untrimmed results or some other unexpected output, or something else.?.?
Note: as I already added in a comment to a prior answer, the use of CONCAT operator vs the equivalent || in SQL source enables use of that source in\across other code pages without a possible issue due to the use of a variant character.
p.s. A CASE statement might be preferred in place of the IF\ELSE constructs
p.p.s. Might be worth review if the SP really should return both the RS and, or just, the OUT parameters
String concatenation can be done with the || operator.
set vEmail = userName || '#' || domain || '.' || tld;
Give that a try.

Correctly inserting literals in PL/PgSQL EXECUTE dynamic queries

The following is part of a plpgsql function. The problem is that the result of source_geom and target_geom is a character varying data type, and therefore I need to surround the both source_geom and target_geom in quotes(' '). The thing is that in plpgsql language how I don't know I can do it.
Here's what I have at the moment:
EXECUTE 'update ' || quote_ident(geom_table) ||
' SET source = ' || source_geom ||
', target = ' || target_geom ||
' WHERE ' || quote_ident(gid_cname) || ' = ' || _r.id;
The error that I am having is the following;
ERROR: syntax error at or near "C03B9E3B66052D400DDEFC2BD0F24140"
LINE 1: ...pdate track_points SET source = 0101000020E6100000C03B9E3B66...
^
QUERY: update track_points SET source = 0101000020E6100000C03B9E3B66052D400DDEFC2BD0F24140, target = 0101000020E610000075690DEF83052D40F88E75CCD4F24140 WHERE ogc_fid = 2
CONTEXT: PL/pgSQL function "create_network" line 26 at EXECUTE statement
Please any suggestions how I can solve this problem.?
Using EXECUTE ... USING with the format() function and its format specifiers will make your code much safer, simpler, easier to read and probably faster.
SQL INJECTION WARNING: If you ever accept source_geom or target_geom from the end user, your code is potentially vulnerable to SQL injection. It is important to use parameterized statements (like EXECUTE ... USING) or failing that, paranoid quoting to prevent SQL injection attacks. Even if you don't think your function takes user input you should still harden it against SQL injection, because you don't know how your app will evolve.
If you're on a newer PostgreSQL with the format function your code can be significantly simplified into:
EXECUTE format('update %I SET source = %L, target = %L WHERE %I = %L',
geom_table, source_geom, target_geom, gid_cname, _r.id);
... which handles identifier (%I) and literal (%L) quoting for you using format specifiers so you don't have to write all that awful || concatenation and quote_literal/quote_ident stuff.
Then, as per the documentation on EXECUTE ... USING you can further refine the query into:
EXECUTE format(
'update %I SET source = $1, target = $2 WHERE %I = $3',
geom_table, gid_cname
) USING source_geom, target_geom, _r.id;
which turns the query into a parameterised statement, clearly separating parameters from identifiers and reducing string processing costs for a more efficient query.
Use extra quotes:
EXECUTE 'update ' || quote_ident(geom_table) ||
' SET source = ''' || source_geom || '''
, target = ''' || target_geom || '''
WHERE ' || quote_ident(gid_cname) || ' = ' || _r.id;

Oracle "ORA-01008: not all variables bound" Error w/ Parameters

This is the first time I've dealt with Oracle, and I'm having a hard time understanding why I'm receiving this error.
I'm using Oracle's ODT.NET w/ C# with the following code in a query's where clause:
WHERE table.Variable1 = :VarA
AND (:VarB IS NULL OR table.Variable2 LIKE '%' || :VarB || '%')
AND (:VarC IS NULL OR table.Variable3 LIKE :VarC || '%')
and I'm adding the parameter values like so:
cmd.Parameters.Add("VarA", "24");
cmd.Parameters.Add("VarB", "test");
cmd.Parameters.Add("VarC", "1234");
When I run this query, the server returns:
ORA-01008: not all variables bound
If I comment out either of the 'AND (....' lines, the query completes successfully.
Why would the query run through alright if I'm only querying with two parameters, but not with three? The error I'm receiving doesn't even make sense
The ODP.Net provider from oracle uses bind by position as default. To change the behavior to bind by name. Set property BindByName to true. Than you can dismiss the double definition of parameters.
using(OracleCommand cmd = con.CreateCommand()) {
...
cmd.BindByName = true;
...
}
It seems daft, but I think when you use the same bind variable twice you have to set it twice:
cmd.Parameters.Add("VarA", "24");
cmd.Parameters.Add("VarB", "test");
cmd.Parameters.Add("VarB", "test");
cmd.Parameters.Add("VarC", "1234");
cmd.Parameters.Add("VarC", "1234");
Certainly that's true with Native Dynamic SQL in PL/SQL:
SQL> begin
2 execute immediate 'select * from emp where ename=:name and ename=:name'
3 using 'KING';
4 end;
5 /
begin
*
ERROR at line 1:
ORA-01008: not all variables bound
SQL> begin
2 execute immediate 'select * from emp where ename=:name and ename=:name'
3 using 'KING', 'KING';
4 end;
5 /
PL/SQL procedure successfully completed.
You might also consider removing the need for duplicated parameter names in your Sql by changing your Sql to
table.Variable2 LIKE '%' || :VarB || '%'
and then getting your client to provide '%' for any value of VarB instead of null. In some ways I think this is more natural.
You could also change the Sql to
table.Variable2 LIKE '%' || IfNull(:VarB, '%') || '%'