Use if, else in function in sql query - sql-server

I use the below query,but throws an error:
CREATE FUNCTION getCustomerPaymentFunc (#customerCode bigint )
RETURNS bigint AS BEGIN
RETURN
( if(select coun from getCustomerPaymentCount (#customerCode))=0)
select 0 as price
else
(select SUM(price) as code
from PaymentLog
where customerCode=#customerCode)
) END
I Use below Two but says:
select statement included within a function cannot return data to client
CREATE FUNCTION getCustomerPaymentFunc (#customerCode bigint )
RETURNS bigint AS BEGIN
RETURN
(
SELECT CASE WHEN (select coun from getCustomerPaymentCount(#customerCode))=0
THEN 0 ELSE 1 END as
(select SUM(price) as code from PaymentLog
where customerCode=#customerCode)
) END

It looks like your intention is to have the function return the sum of price in the PaymentLog table for a given customerCode, or return 0 if the customerCode doesn't exist. If this is correct you could do this:
CREATE FUNCTION getCustomerPaymentFunc (#customerCode bigint) RETURNS bigint AS
BEGIN
DECLARE #result bigint
SET #result= (SELECT ISNULL(SUM(price), 0) FROM PaymentLog WHERE customerCode = #customerCode)
RETURN #result
END
If thecustomerCodedoesn't exist in thePaymentLogtable theSUM()function will returnNULLand you can use either theCOALESCEor theISNULLfunction to replace the NULLvalue with 0.
See MSDN: COALESCE and ISNULL

Related

Getting error while comparing the result of scalar function

We have a scalar function which returns boolean value
CREATE Function func(#name varchar(max))
returns bit
as
Begin
declare #isValid bit
set #isValid=
Case
When Exists(
select Id from TableA where #name in ('nameA','nameB')
) then 1
Else 0
end
return #isValid
End
Now I am trying to use this function to determine the value of a column while inserting into another table. I tried with the below script and its showing syntax error. Please let me know what is missing
Insert into TableB
( Name,Active)
values
(
'abc',
Case
When (select dbo.func('nameA'))=1
then 1
else 0
end
)

How to add loops and compare in stored procedures SQL

I have the following set of number as a varchar and getting the input as an integer var.
#ProductId int
DECLARE #AllowedProductIds varchar(max)
SET #AllowedProductIds ='7002,7058,67,7000,7059,7038'
IF (#ProductId = (SELECT CAST(#AllowedProductIds AS INTEGER)
FROM dbo.SplitString(#AllowedProductIds, ',')))
BEGIN
SET #boolVariable = 1
END
I want to separate the varchar with a delimiter say in my case (,) and compare each one with the input and return the result from the boolean variable.
This is the following code that I have tried and I get an error:
Conversion failed when converting varchar to int
Can somebody please help me out how to do this?
Your cast call is not reading the returned column from the dbo.SplitString call, and instead is trying to evaluate the whole input string as an integer, which it is not.
I don't know the schema of the output of your SplitString function, but let's imagine that it returns something like this:
Input string: '12345,123,234,345'
Output table:
SplitStringItem
12345
123
234
345
Then your call should be:
if #ProductId IN
(
select cast(SplitStringItem AS INTEGER) from dbo.SplitString(#AllowedProductIds, ',')
)
Note the change to use the IN operator rather than the = operator, since you're trying to assess whether a single integer value is in a list of possible values.
As you're using SQL Server you can do this
declare #AllowedProductIds varchar(max), #ProductId int=67
set #AllowedProductIds ='7002,7058,67,7000,7059,7038'
if exists (select * from String_Split(#AllowedProductIds, ',') where Cast(value as int)=#ProductId )
print 'yay'
Or alternatively
declare #AllowedProductIds varchar(max), #ProductId int=67
set #AllowedProductIds ='7002,7058,67,7000,7059,7038'
if exists (select * from String_Split(#AllowedProductIds, ',') where value=Cast(#ProductId as varchar) )
print 'yay'
and
select #boolVariable=
case when exists (select * from String_Split(#AllowedProductIds, ',') where value=Cast(#ProductId as varchar) )
then 1 else 0 end
In SQL Server 2016 you can use string_split() function to do what you are trying to achieve.
Query:
DECLARE #ProductId int,#isHavingBoldAccess int
set #ProductId=7058
DECLARE #AllowedProductIds varchar(max)
SET #AllowedProductIds ='7002,7058,67,7000,7059,7038'
IF #ProductId in
(
select * from STRING_SPLIT(#AllowedProductIds, ',')
)
SET #isHavingBoldAccess = 1
print #isHavingBoldAccess
Output:
1
db<>fiddle here
You can Simplify your Code like this:
Also the above mentioned Error is resolved here.
If the #ProductId matches with the #AllowedProductIds String, the we can assign the Value as 1 else it will takes the default value for the variable #boolVariable. Here its default value is NULL.
DECLARE #AllowedProductIds VARCHAR(MAX),
#boolVariable INT,
#ProductId INT=67
SET #AllowedProductIds ='7002,7058,67,7000,7059,7038'
SELECT #boolVariable = 1
FROM String_Split(#AllowedProductIds, ',')
WHERE CAST(Value AS INTEGER) =#ProductId
SELECT #boolVariable

SQL server Function - Take column name as input parameter

I need to write a SQL function to return column specific values, so I am passing the column name as a parameter to SQL-function to return its corresponding value. Here is the sample function
CREATE FUNCTION GETDATETIME(#columnName VARCHAR(100))
RETURNS DATETIME
AS
BEGIN
RETURN (SELECT TOP 1.#columnName FROM TEST_TABLE )
END
GO
The above function seems to be straight forward, but it not working as expected.
And when I execute the function
SELECT dbo.GETDATETIME('DATETIMECOLUMNNAME')
I am getting this error:
Conversion failed when converting date and/or time from character string.
Can someone help me to identify the issue?
For that you need to write dynamic sql. But Functions won't support execute statement.
So you need to write multiple If conditions for each column.
CREATE FUNCTION GETDATETIME(#columnName VARCHAR(100))
RETURNS DATETIME
AS
BEGIN
DECLARE #RESULT DATETIME;
IF (#columnName = 'ABC')
Begin
SELECT TOP 1 #RESULT = [ABC] FROM TEST_TABLE
END
ELSE IF (#columnName = 'DEF')
Begin
SELECT TOP 1 #RESULT = [DEF] FROM TEST_TABLE
END
ELSE IF (#columnName = 'GHI')
Begin
SELECT TOP 1 #RESULT = [GHI] FROM TEST_TABLE
END
RETURN #RESULT
END
GO
Edit 2:
If your column always return Datetime, then you can do like below.
CREATE TABLE A_DUM (ID INT, STARTDATE DATETIME, ENDDATE DATETIME, MIDDLEDATE DATETIME)
INSERT INTO A_DUM
SELECT 1, '2019-07-24 11:35:58.910', '2019-07-28 11:35:58.910', '2019-07-26 11:35:58.910'
UNION ALL
SELECT 2, '2019-07-29 11:35:58.910', '2019-08-01 11:35:58.910', '2019-07-24 11:35:58.910'
And your function like below
CREATE FUNCTION GETDATETIME(#columnName VARCHAR(100))
RETURNS DATETIME
AS
BEGIN
DECLARE #RESULT DATETIME;
SELECT TOP 1 #RESULT = CAST(PROP AS DATETIME)
FROM A_DUM
UNPIVOT
(
PROP FOR VAL IN (STARTDATE, ENDDATE,MIDDLEDATE)
)UP
WHERE VAL = #columnName
RETURN #RESULT
END
GO
There's a workaround to this, similar to #Shakeer's answer - if you are attempting to GROUP BY or perform a WHERE on a column name, then you can just use a CASE statement to create a clause to match on specific column names (if you know them).
Obviously this doesn't work very well if you have many columns to hard-code, but at least it's a way to achieve the general idea.
E.g. with WHERE clause:
WHERE
(CASE
WHEN #columnname = 'FirstColumn' THEN FirstColumnCondition
WHEN #columnname = 'SecondColumn' THEN SecondColumnCondition
ELSE SomeOtherColumnCondition
END)
Or with GROUP BY:
GROUP BY
(CASE
WHEN #columnname = 'FirstColumn' THEN FirstColumnGroup
WHEN #columnname = 'SecondColumn' THEN SecondColumnGroup
ELSE SomeOtherColumnGroup
END)
No you cannot use dynamic sql in functions in SQL. Please check this link for more info link.
So it is not possible to achieve this by any function, yes you may use stored procedures with output parameter for same.
You may find this link for reference link.

SQL Server user-defined-function using WITH, IF together

I need to create a scalar-valued user defined function in SQL Server. I need to have with clause to store some intermediary tables which will produce the final return result. I also need IF .. ELSE because depending on the input parameter the query to the resutl is different. However, I can't write the code without error combinaing these two elements together. My function would be like this:
CREATE FUNCTION [dbo].[getMyValue](
#inputType int
)
RETURNS float
AS
BEGIN
DECLARE #result float
;
WITH tempTable AS
(
SELECT * from TableA
)
;
IF inputType = 1
set #result = select sum(t.result1) from tempTable
else
selecset #result = select sum(t.result2) from tempTable
return #result
END
GO
But now it complains incorrect syntax near 'if'. If I remove the with clause (and query against some actual table) it compiles, or if I remove IF statements it also compiles. So how can I make them work together?
You cannot use IF like this in the context of an SQL query. Try using the following instead:
DECLARE #result float, #result1 float, #result2 float
WITH tempTable AS
(
SELECT * from TableA
)
SELECT #result1 = sum(case when #inputType = 1 then t.result1 else 0 end),
#result2 = sum(case when #inputType = 2 then t.result2 else 0 end)
FROM tempTable
IF #inputType = 1
SET #result = #result1
ELSE
SET #result = #result2
RETURN #result

Return two items a field and a value from a SQL Server function

I do have a challenge here, I have a table called fileTable with the following columns:
FileID FileName
=================
1 | sdk
2 | mdk
3 | jdk
4 | apk
My challenge here is writing a function that gets passed the filename, if it does exist in the table, return a value 1 and its fileID and if not return a value 0 and ID 0
Now here is what I had started with and I thought about bringing it as a table but then got stuck when trying to use declarations or if statements inside the function
ALTER FUNCTION [dbo].[booker](
#filenumber nvarchar(50))
RETURNS TABLE
AS
RETURN
(
--NB
-- note the challenges am facing i thought of passing a value of FileID to #fn then check if its empty or not, that wont work
--- Declare #fid int; // is not accepted inside here
-- IF EXISTS (SELECT #fid=FILENUMBER FROM [dbo].[File] WHERE FILENUMBER = #filenumber) // the if statement is wrong here too
SELECT FileID
FROM [dbo].[File]
WHERE FileID = #filenumber
-- am left with the above statement where i can extract the FileID but don't know how to check if it exists and if so how to
-- return it with a value 1 that shows the record is in and value 0, fileid=0 if there is no record
)
BUT WHEN I CHANGED mhasan's code to stored procedure it worked
ALTER PROCEDURE [dbo].[booker](
#filenumber nvarchar(50))
AS
IF NOT EXISTS (SELECT 1 FROM [dbo].[File] WHERE FileNumber= #filenumber)
BEGIN
SELECT 0 As FileID, 0 As IsExist
END
ELSE
BEGIN
SELECT FileID, 1 As IsExist
FROM [dbo].[File]
WHERE FileNumber = #filenumber
END
I think am going to use this for a while, thank you tho
From your question, getting data as Table seems to be invalid approach.
You can get the data as single value in function using below query
CREATE FUNCITON [dbo].[booker](#filenumber nvarchar(50)) RETURNS nvarchar(10) DETERMINISTIC
BEGIN
DECLARE fileDetail nvarchar(10);
DECLARE #IDValue INT;
SET fileDetail = '';
SET #IDValue = 0;
SELECT FileID INTO #IDValue
FROM [dbo].[File]
WHERE FileID = #filenumber;
IF IDValue = 0 THEN
SET fileDetail := 0 +'|'+0;
ELSE
SET fileDetail := 1 +'|'+#IDValue;
END IF;
RETURN (fileDetail);
END
Hope this should help you out.
Use multistatement table valued function as below for using multiple code blocks as per your logic. You are using inline table valued function which allows only for single SELECT statement.
ALTER FUNCTION [dbo].[booker](#filenumber nvarchar(50))
RETURNS #ResultTableVariable TABLE (FileID INT, IsExist INT)
AS
BEGIN
IF NOT EXISTS (SELECT 1 FROM [dbo].[File] WHERE FileName= #filenumber)
BEGIN
INSERT INTO #ResultTableVariable (FileID , IsExist)
SELECT 0 , 0
END
ELSE
BEGIN
INSERT INTO #ResultTableVariable (FileID , IsExist)
SELECT FileID, 1
FROM [dbo].[File]
WHERE FileID = #filenumber
END
RETURN
END
This returns a table with two columns FileID and IsExist

Resources