ASP classic - Microsoft SQL and multiple where clauses on an UPDATE - sql

I have the following string but it seems to not like it:
"UPDATE
table
SET a = '', b = '34'
WHERE id = '1000001';
SET a = '1111', b = '11'
WHERE id = '100210';
SET a = '', b = '2'
WHERE id = '8002059';"
In my asp classic code that string is on one line.. Is this the correct way of doing multiple update/where statements?

No, it will give you an error.
Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'table'.
And you can't use multiple where in UPDATE statement.
Try this instead:
UPDATE
[table]
set a =
( case when id IN ( '1000001', '8002059') then ''
when id = '100210' then '1111'
end
),
b =
( case when id = '1000001' then '34'
when id = '100210' then '11'
when id = '8002059' then '2'
end
)
where id in ('1000001', '100210', '8002059');

It will like this better (3 statements).
UPDATE table SET a = '', b = '34' WHERE id = '1000001';
UPDATE table SET a = '1111', b = '11' WHERE id = '100210';
UPDATE table SET a = '', b = '2' WHERE id = '8002059';
Alternatively you can use two CASE statements in your SETs. It won't be as readable but will run slightly more quickly having 1 database round trip rather than 3 if this is a 1-off situation where you frequently need exactly 3 conditional updates performed (unlikely).
UPDATE table SET
a = CASE id WHEN '1000001' THEN '' WHEN '100210' THEN '1111' WHEN '8002059' THEN '' ELSE a END,
b = CASE id WHEN '1000001' THEN '34' WHEN '100210' THEN '11' WHEN '8002059' THEN '2' ELSE b END
WHERE id IN ('1000001', '100210', '8002059');

Related

Why Would Unknown Column Be Referenced in SQL Query

I am in the process of updating some SQL queries to run against MariaDB instead of via SQL Anywhere. One query I'm running is erroring with this:
Error Code: 1054. Unknown column 'choice' in 'field list'
That is for this query:
SELECT
(select firstname||' '||lastname||' ('||service||')' from staff_members where id_number = customer_assignment_reviews.staff_member_id) as Rep,
(select customer_firstname||' '|| customer_lastname from customers where id_number = customer_assignment_reviews.cs_id) as Cus,
last_modified as "Response Date",replace(review_reason,'’','') as "Reason",
(Select choice = CASE
when accepted = 0 then 'No'
when accepted = 1 then 'Yes'
end) as "Accepted?"
FROM customer_assignment_reviews
where staff_member_id in (Select id_number from kar.staff_members where division_id = 6)
and "Response Date" between today() - 7 and today() /* Date Range */
and "Accepted?" = 'No'
Order by 3 desc
Is this error message as straightforward as it sounds? It's simply saying the column "choice" doesn't exist on the target table?
I'm just trying to reason through why this code (which I inherited) would be referencing a column that does not exist. Could something be expected here at runtime?
You don't need to use subquery in SELECT list
SELECT
-- ...
(Select choice = CASE
when accepted = 0 then 'No'
when accepted = 1 then 'Yes'
end) as "Accepted?"
=>
SELECT
CASE
when accepted = 0 then 'No'
when accepted = 1 then 'Yes'
end as "Accepted?"
Additionaly syntax SELECT alias = expression is only T-SQL specific:
SELECT alias = 1
<=>
SELECT 1 AS alias
What is this supposed to mean?
(Select choice = CASE
when accepted = 0 then 'No'
when accepted = 1 then 'Yes'
end) as "Accepted?"
Very importantly, a select is not needed here. You might mean:
(case when accepted = 0 then 'No'
when accepted = 1 then 'Yes'
end) as is_accepted -- prefer to not have to need escape characters
If accepted only takes those two values, you can simplify this to:
elt(accepted + 1, 'No', 'Yes') as is_accepted

case or if else in a where clause Sql Server

I using the following query and I am using case statement in where cause with parmeters
when report_type = 'All' then I need all rows and no selection is necessary, however if I select 'AR' or 'BD' I only need those respective statements to be included. However when I tried implement the following logic it is throwing me and error near by OR not sure where I am doing wrong. Any help will be greatly appreciated.
select * from aging agedet where
(
'All' = {?Report_Type}
OR
(
CASE
WHEN {?Report_type} = 'AR' THEN
(agedet.bkt_type_ha_c <> 5
AND
agedet.extern_ar_flag_yn <> 'Y'
AND
agedet.bad_debt_flag_yn <> 'Y')
CASE
WHEN {?Report_type} = 'Bd' THEN
(agedet.bkt_type_ha_c = 5
AND
agedet.extern_ar_flag_yn = 'Y'
AND
agedet.bad_debt_flag_yn = 'Y')
END )
)

SQL Server CASE statement with mupltiple conditionals syntax

I have a need to add a case statement into a select, but I cannot seem to get the syntax right, could anyone help?
SELECT
uuid = pnt.ID
,extras = (CASE (SELECT pnt.TypeID as [type], pnt.Source as source)
WHEN source = 7 THEN 'a'
WHEN source = 1 AND [type] = 0 THEN 'b'
WHEN source = 8 THEN 'c'
WHEN source = 2 AND [type] = 0 THEN 'd'
WHEN source = 3 AND [type] IN (5,6,7,8) THEN 'e'
ELSE NULL
END)
FROM
Mydata as pnt
There are multiple problems, the select within the case is incorrect, the condition source = 7 is wrong, the combining conditions with an AND is wrong and the condition using IN is incorrect.
I used the answer to Multiple Criteria In Case Statement as a basis for the case statement.
SELECT
#uuid = pnt.ID
,#extras = (CASE WHEN source = 7 THEN
'a'
WHEN source = 1 AND [type] = 0 THEN
'b'
WHEN source = 8 THEN
'c'
WHEN source = 2 AND [type] =0 THEN
'd'
WHEN source = 3 AND [type] IN (5,6,7,8) THEN
'e'
ELSE NULL
END
)
FROM
Mydata as pnt
There are two types of case statements:
A simple case statement that compares an expression to a set of simple expressions to return specific values.
A searched case statement that evaluates a set of Boolean expressions to return specific values.
https://msdn.microsoft.com/en-us/library/ms144841(v=sql.105).aspx
In your script your're "mixing" them, so that your script doesn't work.
This could be a good solution:
SELECT
pnt.ID
,CASE
WHEN pnt.source = 7 THEN 'a'
WHEN pnt.source = 1 AND pnt.TypeID = 0 THEN 'b'
WHEN pnt.source = 8 THEN 'c'
WHEN pnt.source = 2 AND pnt.TypeID = 0 THEN 'd'
WHEN pnt.source = 3 AND pnt.TypeID IN (5, 6, 7, 8) THEN 'e'
ELSE NULL
END
FROM
#Mydata AS pnt
Warning!
If you need to populate single variables (uuid, extras) you have to be sure that your query's result will have only 1 record
SELECT
PNT.ID AS UUID
, CASE
WHEN PNT.source = 7 THEN 'a'
WHEN PNT.source = 1 AND PNT.[type] = 0 THEN 'b'
WHEN PNT.source = 8 THEN 'c'
WHEN PNT.source = 2 AND PNT.[type] = 0 THEN 'd'
WHEN PNT.source = 3 AND PNT.[type] IN (5, 6, 7, 8) THEN 'e'
ELSE NULL
END AS EXTRAS
FROM Mydata AS PNT
As you are already working within the table Mydata a case expression has access to the values held in [source] and [type] without an added select.
I have put the column aliases at the end of each column definition, I believe this is more generally supported by databases than using = for that purpose.
SELECT ID As uuid, CASE WHEN Source = 7 THEN
'a'
WHEN Source = 1 AND TypeID= 0 THEN
'b'
WHEN Source = 8 THEN
'c'
WHEN Source = 2 AND TypeID= 0 THEN
'd'
WHEN Source = 3 AND TypeID IN (5,6,7,8) THEN
'e'
ELSE
NULL
END
AS extras FROM Mydata

SQL Implementing 'IN' operator with 'OR'

I am working on a legacy system which has a custom java implementation for generating SQL queries. That doesn't support 'IN' operation.
To implement 'IN' I have written something like
SELECT * from Q
WHERE IS_HIDDEN = 0 AND ID = 1
OR ID = 2 OR ID = 3 AND IS_DELETED = 0;
I know that the one like below would have been fine.
SELECT * from Q
WHERE IS_HIDDEN = 0 AND (ID = 1
OR ID = 2 OR ID = 3) AND IS_DELETED = 0 ;
Both these return the same result but I'm not too confident about SQL operator priorities. I had read that AND takes precedence
Is it safe to assume that both the SQL statemets are equivalent.
The actual query that I wanted to write is
SELECT * from Q
WHERE IS_HIDDEN = 0 AND ID IN(1, 2, 3) AND IS_DELETED = 0;
The DB in question is oracle 10g.
Update: The reason that this was working is because the oracle CBO rearranges the subclauses in the where clause.
No your queries are not the same
SELECT * from Q
WHERE IS_HIDDEN = 0 AND ID = 1
OR ID = 2 OR ID = 3 AND IS_DELETED = 0;
is like
SELECT * FROM Q WHERE IS_HIDDEN = 0 AND ID = 1
UNION
SELECT * FROM Q WHERE ID = 2
UNION
SELECT * FROM Q WHERE ID = 3 AND IS_DELETED = 0
when you use the parentheses for your ORs then you have the same like the IN-Clause
You can try it: SQLFiddle
You first query is equal to the IN. You should use that:
Your second query is like this:
SELECT * from Q
WHERE (IS_HIDDEN = 0 AND ID = 1) OR ID = 2 OR (ID = 3 AND IS_DELETED = 0);
If IS_HIDDEN is 1 or DELETED Is 1, but ID is 2, your query will still give you records. Try it..

In this example can UPDATE statements be combined?

I quite often have rows of code like the following:
UPDATE my_table SET name = 'x' WHERE Original = 'a'
UPDATE my_table SET name = 'y' WHERE Original = 'b'
UPDATE my_table SET name = 'z' WHERE Original = 'c'
UPDATE my_table SET name = 'k' WHERE Original = 'd'
UPDATE my_table SET name = 'm' WHERE Original = 'e'
UPDATE my_table SET name = 'n' WHERE Original = 'f'
Can I combine/shorten this code into one UpDate statement - or are they best just left as they are?
UPDATE my_table
SET name =
CASE
WHEN Original = 'a' THEN 'x'
WHEN Original = 'b' THEN 'y'
...
END
That will update EVERY row. So if there's an Original value you haven't specified, it will be set to NULL. So you might want to limit the update to just those you want to update, with a WHERE clause, like so:
WHERE Original IN ('a', 'b', ...)
OR, as an alternative, you could use an ELSE statement, which leaves the name value as is, if it doesn't have a match in the WHEN statements, like so:
CASE
WHEN Original = 'a' THEN 'x'
WHEN Original = 'b' THEN 'y'
...
ELSE name
END
You could use a case statement:
UPDATE my_table
SET name =
case Original
when 'a' then 'x'
when 'b' then 'y'
...
else name -- Preserve original
end
The else clause makes sure you're not modifying a name if it's not matched in the case.
You could use a table value constructor and a from clause, if these values aren't already in a table:
update mt set name = t.name
from
my_table mt
inner join
(values
('a','x'),
('b','y'),
('c','z'),
('d','k'),
('e','m'),
('f','n')
) t(original,name)
on
mt.Original = t.original