SQL results operation question - sql

I know I missasked the question, and that's probably the reason I can't find the solution myself:
How do I take a result in a stored procedure and and change the data such as
if column1 = AAA then
column1=Hello
else if column1 = BBB then
column1 = goodbye
and have the data return with the new values?
Thanks

Use the CASE statement:
SELECT CASE
WHEN column1 = 'AAA' THEN 'Hello'
WHEN column1 = 'BBB' THEN 'goodbye'
ELSE ... -- optional
END

these two queries:
UPDATE table_name SET column1='Hello' WHERE column1='AAA'
UPDATE table_name SET column1='goodbye' WHERE column1='BBB'

If you can get to the content of the stored procedure, you should change it to a table-valued function instead - if possible, an inline one (because that has a much higher chance of being able to be optimised).
This will let you query the results and change it as needed:
SELECT CASE column1
WHEN 'AAA' THEN 'Hello'
WHEN 'BBB' THEN 'goodbye'
END as NewColumn,
,*
FROM dbo.yourNewFunction() as t;
If you can't do this, and are very much stuck with a stored procedure, you could wrap it up in OPENROWSET:
SELECT CASE column1
WHEN 'AAA' THEN 'Hello'
WHEN 'BBB' THEN 'goodbye'
END as NewColumn,
, *
FROM OPENROWSET('SQLNCLI','Server=.;Trusted_Connection=Yes;','EXEC dbo.YourProc') as t;
This is a way to treat the output of a procedure as a table expression, but if you can do it without the procedure, that's better still.

you'll have to rename everything starting with my to your actual table names
CREATE PROCEDURE myProc
AS
BEGIN
UPDATE myTable
SET Column1 =
CASE
WHEN 'AAA' THEN 'Hello'
WHEN 'BBB' THEN 'goodbye'
END
WHERE Column1 in ('AAA','BBB')
OUTPUT myTable.myIDColumn, INSERTED.Column1
END
Updates the table and returns only the updated records once you
EXEC myProc
Reference
1. http://technet.microsoft.com/en-us/library/ms177564.aspx

Related

Return a value if no rows selected are found Oracle

Here's my simple query. If I query a record that doesn't exist then I will get nothing returned.
SELECT
CASE WHEN table1.column1= #column1 THEN 'XX'
ELSE 'YY' END from table1 where table1.column2=#column2
It returns no rows selected.
I tried ISNULL() .But not rectified
I need to return 'YY'
Could anyone helpme out..!!
Thanks in Advance!!
The query you have posted has # symbol, which is not the default substitution character for variables in Oracle as in SQL-Server, unless you have used something like
SET DEFINE # and put quotes while passing string literals.Not sure if you are using it that way.
I would suggest you to use a bind variable which is prefixed by a colon :
Regarding your question
I need to return 'YY'
for no rows selected, you could put your case block inside an aggregate function, such as MAX, which will return a row with a null and COALESCE can then handle the nulls to give you the desired value, when there are no rows.
SELECT
COALESCE(
MAX(
CASE
WHEN t.column1 =:column1 THEN 'XX'
ELSE 'YY'
END
),'YY')
FROM
table1 t
WHERE
t.column2 =:column2;
select
case
when coalesce(table1.column1,'empty') = #column1
then 'XX'
else 'YY'
end as SOMETHING
from table1
where coalesce(table1.column2,'empty') = #column2
Coalesce is used to check if the value is null, and if it is, it changes to the value appointed right next to the column name. If you would provide your data, I could change sql query by your need.
Try this
SELECT
CASE WHEN table1.column1= #column1 THEN 'XX'
ELSE 'YY' END from table1 where case when table1.column2=#column2 then table1.column2 else #column2 end = #column2
Note: if there is more than one record in table1 then this query will return YY for all those rows
Keeping it simple and easy for you.
First check if the data is available as per your where condition. If it is then do the rest of the query, if it isn't simply just return YY
for example:
If exists(SELECT * from table1 where table1.column2=#column2)
begin
SELECT
CASE WHEN table1.column1 = #column1 THEN 'XX'
ELSE 'YY' END AS [COLNAME]
from table1 where table1.column2=#column2
end
else
begin
SELECT 'YY' as [COLNAME]
End
to learn more about EXISTS keyword click here

CASE WHEN in WHERE with LIKE condition instead of 1

I have a query with a bunch of OR's inside an AND in the where clause and I'm trying to replace them with CASE WHEN to see if it improves the performance.
The select query inside the stored procedure is something like:
DECLARE #word = '%word%' --These are inputs
DECLARE #type = 'type'
SELECT * FROM table1
WHERE SomeCondition1
AND ( (#type = 'CS' AND col1 like #word)
OR
(#type = 'ED' AND col2 like #word)
....
)
I'm trying to write this query as:
SELECT * FROM table1
WHERE SomeCondition1
AND ( 1= CASE WHEN #type = 'CS'
THEN col1 like #word
WHEN #type = 'ED'
THEN col2 like #word
END )
But SQL 2012 gives the error 'Incorrect Syntax Near Like' for THEN col1 like #word. If I replace THEN col1 like #word with 1 then no complaints but LIKE should return a 0 or 1 anyway.
I tried SELECT (col1 like #word), extra (), etc with no success.
Is there a way to include LIKE in CASE WHEN in WHERE or should I just not bother if using CASE WHEN instead of the original IF's won't make any performance difference?
UPDATE:
This actually didn't make any difference performance wise.
There are is a lot of info online about these 'optional' type stored procedures and how to avoid parameter sniffing performance issues.
This syntax should get you closer though:
AND CASE
WHEN #type = 'CS' THEN col1
WHEN #type = 'ED' THEN col2
END LIKE #word
Just make sure the col1 and col2 datatypes are similar (don't mix INT and VARCHAR)
You should compare query plans between the two syntaxes to ascertain whether it even makes a difference. Your performance issue might be due more to parameter sniffing.
You can also try nested case statements. e.g. based on your latest post, something like:
1 = CASE WHEN #type = 'CandidateStatus'
THEN (CASE WHEN co.[Description] LIKE #text THEN 1 END)
...
END
Here's how I got it to work, now just need to test if it makes any difference to performance. #Nick.McDermaid 's parameter sniffing is worth looking at.
1 = CASE WHEN #type = 'CandidateStatus'
THEN (SELECT 1 WHERE co.[Description] LIKE #text)

Optional Reporting Parameters (is there a better way?)

I have a report with 4 parameters. I would like to make them not required. The problem is the conventional approach to do this, creates 16 OR/AND statements. If I were to have 10 not required parameters the SOL statement would be out of control. This works but is there an easier way?
Here is what I have:
MAIN DATA SET:
select *
from table
where
table.one = #param1 OR #param1 IS NOT NULL
AND.....(etc.etc..)
#param1, #param2,#param3,#param4: (default value null/blank)
Select some_column from any_table UNION SELECT '' as Nothing
The way I've always done it is
WHERE
col1 = isnull(#col1, col1)
and col2 = isnull(#col2, col2)
...etc
So pretty much what you have, with some semantic corrections.

How can I update a record using a correlated subquery?

I have a function that accepts one parameter and returns a table/resultset. I want to set a field in a table to the first result of that recordset, passing in one of the table's other fields as the parameter. If that's too complicated in words, the query looks something like this:
UPDATE myTable
SET myField = (SELECT TOP 1 myFunctionField
FROM fn_doSomething(myOtherField)
WHERE someCondition = 'something')
WHERE someOtherCondition = 'somethingElse'
In this example, myField and myOtherField are fields in myTable, and myFunctionField is a field return by fn_doSomething. This seems logical to me, but I'm getting the following strange error:
'myOtherField' is not a recognized OPTIMIZER LOCK HINTS option.
Any idea what I'm doing wrong, and how I can accomplish this?
UPDATE:
Based on Anil Soman's answer, I realized that the function is expecting a string parameter and the field being passed is an integer. I'm not sure if this should be a problem as an explicit call to the function using an integer value works - e.g. fn_doSomething(12345) seems to automatically cast the number to an string. However, I tried to do an explicit cast:
UPDATE myTable
SET myField = (SELECT TOP 1 myFunctionField
FROM fn_doSomething(CAST(myOtherField AS varchar(1000)))
WHERE someCondition = 'something')
WHERE someOtherCondition = 'somethingElse'
Now I'm getting the following error:
Line 5: Incorrect syntax near '('.
I have never done anything like this so .... all the code I have seen uses a schema on the function name - so something like:
FROM dbo.fn_doSomething(myOtherField)
seems like a compiler bug in SQL 2000
try in Server 2005 and join the table-valued function using CROSS APPLY or OUTER APPLY
also try this, guru huys
CREATE FUNCTION FCN_pruebaChicaBorrame(#numerito int)
RETURNS #returnTable TABLE (numerito int)
AS
BEGIN
insert into #returnTable values(#numerito)
return
END
Select * from FCN_pruebaChicaBorrame(20)
Select col_1
from ( select 1 as col_1
union select 2
union select 3) as tablita
Select col_1, (select * from dbo.FCN_pruebaChicaBorrame(20) as fcnTable)
from ( select 1 as col_1
union select 2
union select 3) as tablita
Select col_1, (select * from dbo.FCN_pruebaChicaBorrame(col_1) as fcnTable)
from ( select 1 as col_1
union select 2
union select 3) as tablita
Select col_1, (select * from dbo.FCN_pruebaChicaBorrame(case when 1=1 then 20 else 21) as fcnTable)
from ( select 1 as col_1
union select 2
union select 3) as tablita
I searched on google for this error and one person talks about missing single quotes in search condition. Is that the case with your function code? link to related blog
It seems that (at least in SQL Server 2000) you can't pass a column value to a table valued function. I had to set up a scalar function to get around this.

Like in CASE statement not evaluating as expected

Given this data:
CREATE TABLE tmpTable(
fldField varchar(10) null);
INSERT INTO tmpTable
SELECT 'XXX'
UNION ALL
SELECT 'XXX'
UNION ALL
SELECT 'ZZZ'
UNION ALL
SELECT 'ZZZ'
UNION ALL
SELECT 'YYY'
SELECT
CASE WHEN fldField like 'YYY' THEN 'OTH' ELSE 'XXX' END AS newField
FROM tmpTable
The expected resultset is:
XXX
XXX
XXX
XXX
OTH
What situation would casue SQL server 2000 to NOT find 'YYY'? And return the following as the resultset:
XXX
XXX
XXX
XXX
XXX
The problem is with the like 'YYY', I have found other ways to write this to get it to work, but I want to know why this exact method doesn't work. Another difficulty is that it works in most of my SQL Server 2000 environments. I need to find out what is different between them to cause this. Thanks for your help.
Check your service pack. After upgrading my SQL 2000 box to SP4 I now get the correct values for your situation.
I'm still getting the swapped data that I reported in my earlier post though :(
If you do SELECT ##version you should get 8.00.2039. Any version number less than that and you should install SP4.
I ran the code on a SQL 2000 box and got identical results. Not only that, but when I ran some additional code to test I got some VERY bizarre results:
CREATE TABLE dbo.TestLike ( my_field varchar(10) null);
GO
CREATE CLUSTERED INDEX IDX_TestLike ON dbo.TestLike (my_field)
GO
INSERT INTO dbo.TestLike (my_field) VALUES ('XXX')
INSERT INTO dbo.TestLike (my_field) VALUES ('XXX')
INSERT INTO dbo.TestLike (my_field) VALUES ('ZZZ')
INSERT INTO dbo.TestLike (my_field) VALUES ('ZZZ')
INSERT INTO dbo.TestLike (my_field) VALUES ('YYY')
GO
SELECT
my_field,
case my_field when 'YYY' THEN 'Y' ELSE 'N' END AS C2,
case when my_field like 'YYY' THEN 'Y' ELSE 'N' END AS C3,
my_field
FROM dbo.TestLike
GO
My results:
my_field C2 C3 my_field
---------- ---- ---- ----------
N XXX N XXX
N XXX N XXX
Y YYY N YYY
N ZZZ N ZZZ
N ZZZ N ZZZ
Notice how my_field has two different values in the same row? I've asked some others at the office here to give it a quick test. Looks like a bug to me.
It worked as expected on my SQL 2005 installation. If it works on other machines, it sounds like you've got an environment difference. Try comparing your connection properties in SQL Server Management Studio for a connection that works and one that doesn't to see if you can figure out what the differences are.
I am an Oracle person, not a SQL*Server person, but it seems to me you should be either:-
SELECT
CASE WHEN fldField like '%YYY%' THEN
'OTH'
ELSE 'XXX'
END AS newField
FROM
tmpTable
or ...
SELECT
CASE WHEN fldField = 'YYY' THEN
'OTH'
ELSE 'XXX'
END AS newField
FROM
tmpTable
The second is the direction I'd go in, as at least in Oracle equality resolves quicker than like.
When you use LIKE without specifying any search criteria, it behaves like an = comparison. In your example, I would expect it to work properly. In your real data, you probably have a hidden (non-printable) character in your data (think about Carriage Return, Line Feed, Tab, etc....).
Take a look at this example...
Declare #tmpTable TABLE(
fldField varchar(10) null);
INSERT INTO #tmpTable
SELECT 'XXX'
UNION ALL
SELECT 'XXX'
UNION ALL
SELECT 'ZZZ'
UNION ALL
SELECT 'ZZZ'
UNION ALL
SELECT 'YYY'
UNION ALL
SELECT 'YYY' + Char(10)
SELECT CASE WHEN fldField like 'YYY' THEN 'OTH' ELSE 'XXX' END AS YourOriginalTest,
CASE WHEN fldField like 'YYY%' THEN 'OTH' ELSE 'XXX' END AS newField
FROM #tmpTable
You'll notice that the last piece of data I added is YYY and a Line Feed. If you select this data, you won't notice the line feed in the data, but it's there, so your LIKE condition (which is acting like an equal condition) doesn't match.
The common 'hidden' characters are Tab, Carriage Return, and Line Feed. To determine if this is causing your problem...
Select *
From Table
Where Column Like '%[' + Char(10) + Char(9) + Char(13) + ']%'
What a cute bug. I think I know the cause. If I'm right, then you'll get the results you expect from:
SELECT
CASE
WHEN fldField like 'YYY ' -- 7 spaces
THEN 'OTH'
ELSE 'XXX'
END as newField
from tmpTable
The bug is that varchar(10) is behaving like char(10) is supposed to. As for why it doesn't, you'll need to understand the old trivia question of how two strings with no metacharacters can be = but not LIKE each other.
The issue is that a char(10) is internally supposed to be space padded. The like operator does not ignore those spaces. The = operator is supposed to in the case of chars. Memory tells me that Oracle ignores spaces for strings in general. Postgres does some tricks with casting. I have not used SQL*Server so I can't tell you how it does it.
How about fldField = '%YYY%'?
By adding (%) to the expression , it will work fine.
SELECT
CASE
WHEN fldField like '%YYY%' THEN 'OTH'
ELSE 'XXX' END AS newField
END
You aren't specifying what you are selecting and checking the CASE against...
SELECT CASE fldField WHEN 'YYY'
THEN 'OTH' ELSE 'XXX' END AS newField FROM tmpTable