I have a stored procedure which has a insert statement.The procedure executes an insert statement when the user provides all the values as 0. If the user provides differnt values then a error statement should be returned.
case when #test1=0,#test2=0,#test3=0 then
{Insert statement}
Else
Case when #test1=0,#test2=0,#test3=1
{select “All cases should be 0”}
Else
Select “Please provide data”
In this case I thought case conditions works fine but after reading documentation and some other links it seems syntactically false to write such a statement.
Anyother possible way to solve the problem.
For control flow in T-SQL, use if, not case. Something like this:
if #test1=0 and #test2=0 and #test3=0
begin
{Insert statement}
end;
Else if #test1=0 and #test2=0 and #test3=1
begin
{select “All cases should be 0”}
end
Else
begin
Select “Please provide date”
end;
You can use IF and to check each variable with 0 value then COALESCE and NULLIF are helpful as below:
IF (#test1 = 0 AND #test2 = 0 AND #test3 = 0)
BEGIN
INSERT INTO tmpTable(val1)
SELECT val1 FROM <table_name>
END
ELSE IF COALESCE(NULLIF(#test1, 0), NULLIF(#test2, 0), NULLIF(#test3, 0)) IS NOT NULL
BEGIN
SELECT 'All cases should be 0'
END
ELSE
BEGIN
SELECT 'Please provide data'
END
Related
I am trying to insert values into a temp table via a cursor and if they have a period on the end, I would like to remove the period. Here is the code I am having syntax issues with.
WHILE ##FETCH_STATUS = 0
BEGIN
CASE SELECT CHARINDEX('.',REVERSE(#Category))
WHEN 1
THEN INSERT INTO #Category VALUES (SUBSTRING(#Category,1,LEN(#Category)-1)))
END;
What am I doing incorrectly here? I'm open to more efficient answers but would also like to know how to solve it this way.
CASE yields an expression, not a statement. You are looking for the IF statement.
As for a better way to do this: Scrap the cursor and use an INSERT INTO ... SELECT ... WHERE CHARINDEX('.', REVERSE(category)) = 1 statement.
CASE is used to compute an expression, not control program flow. Use IF instead:
WHILE ##FETCH_STATUS = 0
BEGIN
IF CHARINDEX('.',REVERSE(#Category)) = 1
INSERT INTO #Category VALUES (SUBSTRING(#Category,1,LEN(#Category)-1)))
END;
Although if #Category is computed from an expression off of your cursor then you may see significant improvement by using an INSERT INTO instead of looping and executing individual INSERT statements.
In my SQL Server stored procedure, I have a number of IF blocks.
IF #CurrentStatus IN (1, 4) AND #RoleID IN ('ADMN', 'PMGR', 'SMGR', 'DMGR', 'DESI', 'DERO')
BEGIN
-- SELECT query...
END
IF #CurrentStatus = 2 AND #RoleID IN('ADMN')
BEGIN
-- SELECT query...
END
There are several more IF blocks like these. When none of the queries are executed because the conditions of the IF are not met, there will be no data returned. I have a query I want to return as the default if there is no other data being returned. How can I check if any data is being returned at the end of my stored procedure?
I tried checking if any queries had been executed with IF ##ROWCOUNT = 0 but when one of the IF blocks executed, I would get 2 result sets.
If I understand correctly, you could use If / Else If / Else, like this...
IF #CurrentStatus IN (1, 4) AND #RoleID IN ('ADMN', 'PMGR', 'SMGR', 'DMGR', 'DESI', 'DERO')
BEGIN
-- SELECT query...
END
Else IF #CurrentStatus = 2 AND #RoleID IN('ADMN')
BEGIN
-- SELECT query...
END
Else
BEGIN
-- Default query
END
I have few experiences with t sql and I have to write a stored.
This is my stored:
USE myDatabase
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[myStored]
(
#myPar1 INT,
#myPar2 SMALLDATETIME
)
AS
BEGIN
SET NOCOUNT ON
IF EXISTS (
SELECT
1
FROM
myTable1
WHERE
myPar1 = #myPar1
AND myPar2 = #myPar2
)
BEGIN
DELETE FROM
myTable1
WHERE
myPar1 = #myPar1
AND myPar2 = #myPar2
END
ELSE
IF EXISTS (
SELECT
1
FROM
myTable2
WHERE
myPar2 = #myPar2
)
BEGIN
INSERT INTO
myTable1
(myField1, myField2, myField3, myField4)
VALUES
(#myPar1, #myPar2, '', 1)
END
ELSE
IF EXISTS (
SELECT
1
FROM
myTable3
WHERE
myPar2 = #myPar2
)
BEGIN
INSERT INTO
myTable1
(myField1, myField2, myField3, myField4)
VALUES
(#myPar1, #myPar2, '', 1)
END
END
And these are my questions:
1 - Are there macroscopic errors?
2 - Someone suggest to use "SELECT CASE" someone else to use "IF ... ELSE", what's the difference? And what is the best option for my stored?
3 - I'm not sure about the use of the "BEGIN ... END" statement, in particular in combination with "IF ... ELSE" statement. What does it mean? Is it necessary to put "BEGIN ... END" inside the "IF ... ELSE" statement? Also for executing a single instruction?
For a single IF Statement
IF (Some Condition) --<-- If condition is true control will get inside the
BEGIN -- BEGIN ..END Block and execute the Code inisde
/* Your Code Here*/
END
All the single IF statements will check the Conditions Independently.
ONE IF with ONE ELSE
IF (Some Condition) --<-- If condition is true control will get inside the
BEGIN -- BEGIN ..END Block and execute the Code inisde
/* Your Code Here*/ -- IF not true control will jump to Else block
END
ELSE --<-- You dont mention any condition here
BEGIN
/* Your Code Here*/
END
Only One block of code will execute IF true then 1st block Otherwsie ELSE block of code.
Multiple IFs and ELSE
IF (Some Condition) --<--1) If condition is true control will get inside the
BEGIN -- BEGIN ..END Block and execute the Code inisde
/* Your Code Here*/ -- IF not true control will check next ELSE IF Blocl
END
ELSE IF (Some Condition) --<--2) This Condition will be checked
BEGIN
/* Your Code Here*/
END
ELSE IF (Some Condition) --<--3) This Condition will be checked
BEGIN
/* Your Code Here*/
END
ELSE --<-- No condition is given here Executes if non of
BEGIN --the previous IFs were true just like a Default value
/* Your Code Here*/
END
Only the very 1st block of code will be executed WHERE IF Condition is true rest will be ignored.
BEGIN ..END Block
After any IF, ELSE IF or ELSE if you are Executing more then one Statement you MUST wrap them in a BEGIN..END block. not necessary if you are executing only one statement BUT it is a good practice to always use BEGIN END block makes easier to read your code.
Your Procedure
I have taken out ELSE statements to make every IF Statement check the given Conditions Independently now you have some Idea how to deal with IF and ELSEs so give it a go yourself as I dont know exactly what logic you are trying to apply here.
CREATE PROCEDURE [dbo].[myStored]
(
#myPar1 INT,
#myPar2 SMALLDATETIME
)
AS
BEGIN
SET NOCOUNT ON
IF EXISTS (SELECT 1 FROM myTable1 WHERE myPar1 = #myPar1
AND myPar2 = #myPar2)
BEGIN
DELETE FROM myTable1
WHERE myPar1 = #myPar1 AND myPar2 = #myPar2
END
IF EXISTS (SELECT 1 FROM myTable2 WHERE myPar2 = #myPar2)
BEGIN
INSERT INTO myTable1(myField1, myField2, myField3, myField4)
VALUES(#myPar1, #myPar2, '', 1)
END
IF EXISTS (SELECT 1 FROM myTable3 WHERE myPar2 = #myPar2)
BEGIN
INSERT INTO myTable1(myField1, myField2, myField3, myField4)
VALUES(#myPar1, #myPar2, '', 1)
END
END
I don't see any macroscopic error
IF ELSE statement are the one to use in your case as your insert or delete data depending on the result of your IF clause. The SELECT CASE expression is useful to get a result expression depending on data in your SELECT statement but not to apply an algorithm depending on data result.
See the BEGIN END statement like the curly brackets in code { code }. It is not mandatory to put the BEGIN END statement in T-SQL. In my opinion it's better to use it because it clearly shows where your algorithm starts and ends. Moreover, if someone has to work on your code in the future it'll be more understandable with BEGIN END and it'll be easier for him to see the logic behind your code.
There are no errors in this script.
Case statement is for expression evaluation and not for statement execution. Hence, cannot be used in this current requirement. For more details about case statement look at http://msdn.microsoft.com/en-us/library/ms181765.aspx
Usually, a statement can be single or a compound. Compound ones are a combination of statements. For an IF condition, one can specify a single or compound statement and SQL server chose to group it inside a BEGIN .. END (unlike few other databases/programming languages). This is same for ELSE. Hence, IF should be followed by BEGIN...END and ELSE should be followed by BEGIN...END. For more details please refer to http://msdn.microsoft.com/en-us/library/ms182717(v=sql.120).aspx
My query like this
case when statement1 = statement2 then offer1
if offer1 is have value means then i need to display offer1 value will be 'Yes'
How to write the query for this?
You can nest multiple CASE expressions like so:
CASE
WHEN statement1 = statement2
THEN
CASE WHEN offer1 IS NOT NULL THEN 'Yes' ELSE ... END
END
You can use Stored procedures and return a value depending on the conditions you need, in the stored procedures you can design your conditions using normal if statements, take a look at this example from here:
Create procedure dbo.Prc
#Value varchar(50),
#Result bit OUTPUT
AS
Begin
If exists (select 1 from YourTable where Field=#Value)
set #Result=1
Else
set #Result=0
End
I tried to ask this question before but I don't think I explained myself very well. So here it is: asp.net 2.0 app hitting a SQL 2008 backend. This seems simple but I can't get it. 1 table. The user selects a status. The query should return all records = the chosen status only. If the user select "All Status", then ALL records should be returned, including those with a status = null (which is the part that is hosing me).
Ex:
CASE 1: User selects Status = "Satisfied"; ONLY satisfied records are return
CASE 2: User selects All Status = everything is returned, satisfied AND nulls and anything else
I tried passign in a wildcard but this doesn't return nulls. I tried dynamically buildign the query but I would like to avoid it.
For the case where you want them all, how about: (am I missing something?)
SELECT * FROM <tablename>
SELECT * FROM <tablename> WHERE Status = '*' OR Status IS NULL
...or '%' or whatever wildcard your SQL implementation uses.
...or if you really have no other conditions following this, just select *...
Try this in a stored procedure.
--Pass in #status as a parameter
DECLARE #Status varchar(100)
IF #Status = 'All Status'
BEGIN
SELECT * FROM tablename
END
ELSE
BEGIN
SELECT * FROM tablename where statusfield = #Status
END
One option is
declare #status varchar(50)
SELECT * FROM <tablename> WHERE (#status is null) or (Status = #status)
if you pass null in for the #status parameter then it will return all records. If you pass 'satisfied' or whatever then it will return just those matchng records.
If doing this in SQL 2008, be sure you have SP1 and Cumulative Update 5 installed. Further, I would recommend adding the WITH RECOMPILE option to the procedure. Under those conditions it will be as performant as embedded SQL or even using unions.
See the following article for an indepth discussion of the myriad of ways to perform searching in SQL 2008: Dynamic Search Conditions in T-SQL
The problem is that SQL's = operator always returns NULL when one of the operands is NULL, so using status = '%' indeed doesn't work. The best method is to just not include a condition on status if you want all of them. You can add extra NULL tests to the query, but that again is building it dynamically, I don't see a way to avoid that...
basically your statement will be for 'Statisfied'
SELECT * FROM testtab WHERE
COALESCE(statuscolumn, '') LIKE '%Statified'
for 'All Status' it will be
SELECT * FROM testtab WHERE
COALESCE(statuscolumn, '') LIKE '%'
you could use this statment and if selection is 'All Status' then pass a '' for the #status from your UI
SELECT * FROM testtab WHERE
COALESCE(statuscolumn, '') LIKE '%' || #status
Or you can use this one and when you pass the selection from UI make sure it has a '%' (wild char) appended to your status when it not 'All Status'. When its 'All Status' just pass '%' for the #status
SELECT * FROM testtab WHERE
COALESCE(statuscolumn, '') LIKE #status
oh your db is mssql? :) then you will need to replace the collace(statuscolumn, '') with isnull(statuscolumn, '').
Just skip the where clause or the part that is about the status field, example:
SELECT * from table_1 Where status = 'Satisfied'
and
SELECT * from table_1
When you want all records, you have to exclude STATUS from your WHERE clause (or use a UNION and a select statement where STATUS IS NULL).
Depending on what version of SQL you are using, you might be able to use an IF..ELSE... statement.
IF Status='ALL' THEN
... A SELECT statement where STATUS is NOT included in the WHERE
ELSE
... A SELECT statement that has a WHERE with only the status you are looking for
SELECT * FROM <tablename> WHERE isnull(Status,'*') = '*'
Assuming you're passing a variable to an SP:
SELECT * FROM Table WHERE Status CASE #status WHEN 'All status' THEN Status ELSE #status END
Otherwise, you need to concatenate in the selected value within quotes at both places where it currently says #status
The idea is what to do when the users chooses 'All Status'. By setting the param to NULL, you can use the isnull and then each [status] field just needs to equal itself. I've used ISNULL to set to '' to avoid having NULL = NULL>
declare #param_choice varchar(25)
if #param_choice = 'All Status'
Begin
#param_choice = NULL
End
-- get your results
Select * from Some_Table
Where IsNull([Status], '') = IsNull(#param_choice, IsNull([Status], ''))
You'll get the best performance from:
IF #status IS NULL
BEGIN
SELECT t.*
FROM TABLE t
END
ELSE
BEGIN
SELECT t.*
FROM TABLE t
WHERE t.status = #status
END
The next option is to use:
SELECT t.*
FROM TABLE t
WHERE (#status IS NULL OR t.status = #status)
...but that is not sargable.
I do not believe that anyone suggested using a UNION.
SELECT t.*
FROM TABLE t
WHERE (#status IS NULL)
UNION ALL
SELECT t.*
FROM TABLE t
WHERE (t.status = #status)
If #status is NULL, then the first query in the union is executed, and t.status = #status is clearly always false, so the second query in the union is not executed at all.
If #status is not null, then the first query in the union is not exected at all, and the second one is.
Importantly, since ISNULL, COALESCE or a function are not used on t.status or on #status, then if there is an index on status, it can be used. That is, the predicate is SARGABLE.
And I used UNION ALL (instead of UNION) to prevent a SORT and DISTINCT operation that can be very slow.