Problems with SQL EXISTS - sql-server

I'm going mad on this one. I have the following SP:
ALTER PROCEDURE [BankImport].[spBI_getIsBatchUnique]
#batchName varchar = 500
AS
BEGIN
SET NOCOUNT ON;
IF (EXISTS (SELECT 1 FROM [ACN_Main].[BankImport].[tblBI_Jobs]
WHERE [batchNumber] = #batchName))
BEGIN
SELECT 1
END
ELSE
BEGIN
SELECT 0
END
END
GO
But whatever the request is, I always get back 0!
I tried to modify it in several ways but with no success!
What I need to do is check if there is a record with that batch number and return true, otherwise return false.
Any tip?
Thanks

Your input parameter looks a bit funny
#batchName varchar = 500
Should it have been this?
#batchName varchar(500)
Ie set the length of the varchar datatype, how you currently have it, 500 is the default value for the batchName param.

I think because you compare batchNumber and batchName, try
EXISTS (SELECT 1 FROM [ACN_Main].[BankImport].[tblBI_Jobs]
WHERE [batchName] = #batchName)

Related

Simple SQL UPDATE works in Console but not as Stored Procedure

I know this is a very simple SQL routine, so I am confused as why it does not actually UPDATE.
These work perfectly on their own:
UPDATE ourwebsite.dbo.dealer
SET Active = 0
WHERE dealercode = 12345
UPDATE ourwebsite.dbo.reps
SET username = username + '_LR-3.0'
WHERE dealercode = 12345
But when I try to make them into a Stored Procedure, they seem ok and execute ok, but nothing updates.
#DealerCode VARCHAR
AS
SET NOCOUNT ON;
UPDATE ourwebsite.dbo.dealer
SET Active = 0
WHERE DealerCode = #DealerCode
UPDATE ourwebsite.dbo.reps
SET username = username + '_LR-3.0'
WHERE DealerCode = #DealerCode
END TRY
I am sure I must be missing something?
Thank you for your attention.
You have not specified length for your parameter
#DealerCode VARCHAR
so by default, it takes as VARCHAR(1). You can print or select #DealerCode in your procedure to check the same.
from you query
UPDATE ourwebsite.dbo.dealer
SET Active = 0
WHERE dealercode = 12345
UPDATE ourwebsite.dbo.reps
SET username = username + '_LR-3.0'
WHERE dealercode = 12345
I assumed that dealercode type is numeric because you didn't put ('...') on 12345, you could try this query that i made some bit modification on it
AS #DealerCode NUMERIC
BEGIN TRANSACTION
BEGIN TRY
SET NOCOUNT ON;
UPDATE ourwebsite.dbo.dealer
SET Active = 0
WHERE DealerCode = #DealerCode
UPDATE ourwebsite.dbo.reps
SET username = username + '_LR-3.0'
WHERE DealerCode = #DealerCode
-- Commit the updates into the table
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- Execute rollback upon error retrieval routine.
ROLLBACK TRANSACTION
END CATCH;
It's hard without seeing your entire procedure, as there is an END TRY at the bottom with no BEGIN TRY, so your statements might not even be executed because the execution jumps to the CATCH. Also make sure you are not starting a transaction without committing it.
Aside from that, there is a difference between your manual query and your procedure which is the #DealerCode data type. In your manual query is an INT (or numeric) while in your SP it's a VARCHAR of undeclared length. Check which data type is your dealercode column from your ourwebsite.dbo.reps table and make sure your variable is the same type. Also always indicate the length of your VARCHAR fields.
Test the following code and it will update your records, as it's the same as your stand-alone query:
CREATE PROCEDURE dbo.TestUpdate
#dealercode INT
AS
BEGIN
UPDATE ourwebsite.dbo.dealer
SET Active = 0
WHERE dealercode = #dealercode
UPDATE ourwebsite.dbo.reps
SET username = username + '_LR-3.0'
WHERE dealercode = #dealercode
END
If this works, either remove your BEGIN TRY ... END TRY and your entire CATCH to see exactly the error you are getting, or make sure you do a RAISERROR on your catch with the corresponding ERROR_MESSAGE(). Example:
CREATE PROCEDURE dbo.YourProcedure
#dealercode VARCHAR(20)
AS
BEGIN
BEGIN TRY
-- Your operations here
SELECT 1 / 0
END TRY
BEGIN CATCH
DECLARE #v_ErrorMessage VARCHAR(MAX) = CONVERT(VARCHAR(MAX), ERROR_MESSAGE())
-- Rollback if you have to
RAISERROR (#v_ErrorMessage, 16, 1)
END CATCH
END

Check if there are any records in a table which may not exist

I have to check if some records with specific conditions exist in a table which may not exist and I must do this in a scalar function.
Here is my code:
CREATE FUNCTION CheckIfRecordsExistInTestTable()
RETURNS INT
BEGIN
DECLARE #Result INT
SELECT #Result =
CASE WHEN OBJECT_ID('TestTable') IS NULL THEN 0
ELSE
CASE WHEN EXISTS(SELECT * FROM TestTable) THEN
1
ELSE
0
END
END
RETURN #Result
END
While trying it in SQL Server executing the following statement:
SELECT dbo.CheckIfRecordsExistInTestTable()
Whenever TestTable exists it returns my expected result. But whenever it does not, SQL Server raises an exception (Invalid object name 'TestTable') and I cannot get what I expect (I want a zero return value in this situation).
So what do you propose to do for this problem which can be coded to a scalar function?
The other answer gives a correct workaround.
As to why you are getting the problem...
This is a compile time error.
If the statement references a non existent object compilation is deferred until just before execution, but still eventually the whole statement needs to be compiled into an execution plan before it is executed.
This fails when the table doesn't exist and execution of that statement doesn't even begin.
(Execution plan that it tries to create - using a passthru predicate to avoid evaluation of the condition if the CASE not met)
In the workaround the SELECT against testtable is moved into a different statement. Compilation of this statement is still deferred and as the statement is never executed all works fine.
Try changing the function like this
CREATE FUNCTION Checkifrecordsexistintesttable()
returns INT
BEGIN
DECLARE #Result INT
IF Object_id('TestTable') IS NULL
SET #Result = 0
ELSE
SELECT #Result = CASE
WHEN EXISTS(SELECT 1 FROM testtable) THEN 1
ELSE 0
END
RETURN #Result
END;
To know more about the reason behind the error you are getting check Martin's answer.
update function like this:
CREATE FUNCTION CheckIfRecordsExistInTestTable()
RETURNS INT
BEGIN
DECLARE #Result INT
SELECT #Result = case when count(1) = 0 then 0 else 1 end from sys.tables where name = 'TestTable'
RETURN #result
END

SQL Server : Query not running as needed

I am working with Sage Evolution and do a lot of the back end stuff to customize it for our company.
I need to write a query where, when a user enters a negative quantity the system must not allow the transaction, however when the user enters a negative quantity and the product belongs to the "chemicals" group it needs to process the transaction.
Here is my code I have written so far.
DECLARE
#iAfterfQuantity Int;
#iAfteriStockCodeID Int;
#iAfterStockItemGroup VarChar
SELECT
#iAfterfQuantity = fQuantity,
#iAfteriStockCodeID = iStockCodeID
FROM
INSERTED
SELECT
#iAfterStockItemGroup = ItemGroup
FROM
dbo.stkItem
WHERE
StockLink = #iAfteriStockCodeID
BEGIN
IF #iAfterfQuantity < 0 AND #iAfterStockItemGroup <> 'chemicals'
BEGIN
RAISERROR ('',16,1)
ROLLBACK TRANSACTION
END
END
This is a task better suited for a check constraint then for a trigger, especially considering the fact that you are raising an error.
First, create the check function:
CREATE FUNCTION fn_FunctionName
(
#iAfterfQuantity Int,
#iAfteriStockCodeID Int
)
RETURNS bit
AS
BEGIN
DECLARE #iAfterStockItemGroup VarChar(150) -- Must specify length!
SELECT #iAfterStockItemGroup = ItemGroup FROM dbo.stkItem WHERE StockLink=#iAfteriStockCodeID
IF #iAfterfQuantity < 0 AND #iAfterStockItemGroup <> 'chemicals'
RETURN 0
RETURN 1 -- will be executed only if the condition is false...
END
Then, alter your table to add the check constraint:
ALTER TABLE YourTableName
ADD CONSTRAINT ck_ConstraintName
CHECK (dbo.fn_FunctionName(fQuantity, iStockCodeID) = 1)
GO

How to know there are 0 result in select

if I have a SQL scripts to check a select statement on a table & output those conditions that has no result, How do I do this. I have variables & fetch & next to go thru each row in the table.
Example:
declare #1 varchar(10)
declare #2 varchar(10)
declare #1 cursor for
select userid from users
declare #2 cursor for
select pay from pays where pay_userid=#1
then here if there is no records in pays for certain userid, output to screen or
I did insert into a temp table
But my issue/problem is not those userids not found will not be output due to the result for the last query has no result for those userids.
Maybe you can use "SELECT COUNT(*) FROM ....." at first to judge if there is any result in the query.
You can get the COUNT of your query, and then check if that COUNT is > 0, do your SELECT, otherwise, do something else.
FETCH NEXT FROM your_cursor;
IF ##FETCH_STATUS = 0
BEGIN
-- do your stuff
END
After select statement you can check ##ROWCOUNT variable like this:
SELECT ...
IF ##ROWCOUNT = 0
PRINT 'select statement returned empty result'

Setting output parameters in SELECT statement with an IF EXISTS check

I am trying to make an efficient SQL stored procedure for retrieving user data from my database, but I am running into a syntax issue I can't seem to figure out.
Basically, I want to assign my output variable within my SELECT statement. I also want to see if the user actually exists by IF EXISTS. Unfortunately, I can't seem to do both.
Here is my procedure:
CREATE PROCEDURE [dbo].FindUser(#UserID binary(16), #UserExists bit OUTPUT, #Name
nvarchar(MAX) OUTPUT)
AS
SET NOCOUNT ON
IF EXISTS (SELECT #Name = Name FROM Users WHERE UserID = #UserID)
BEGIN
SET #UserExists = 1
END
RETURN
Currently, it gives me an "SQL46010 :: Incorrect syntax near #Name." error.
If I remove IF EXISTS, the statement compiles fine!
Why does the IF EXISTS check cause a syntax error?
set #UserExists = 0;
select #Name = Name,
#UserExists = 1
from Users
where UserID = #UserID;
SET NOCOUNT ON
IF EXISTS (SELECT 1 FROM Users WHERE UserID = #UserID)
BEGIN
SET #UserExists = 1
/* do other stuff here select user name or whatever */
END
If there is a record for #UserID in users table Selecting 1 will return true for exists clause and control will enter the BEGIN..END block.

Resources