Count on SQL Function return value - sql

I am trying to count the number of records in my table that make a function I created return 1. Here is what I have:
CREATE FUNCTION isErrorMismatch
(#theType nvarchar(1), #theExCode nvarchar(2))
RETURNS bit
AS
BEGIN
DECLARE #theTypeAsInt int
SET #theTypeAsInt = CAST(#theExCode AS INT)
DECLARE #returnValue bit
SET #returnValue = 0
IF #theType = 'A'
IF #theTypeAsInt >= 10 AND #theTypeAsInt <= 17
SET #returnValue = 0
ELSE
SET #returnValue = 1
ELSE IF #theType = 'B'
IF #theTypeAsInt >= 18 AND #theTypeAsInt <= 26
SET #returnValue = 0
ELSE
SET #returnValue = 1
ELSE IF #theType = 'C'
IF #theTypeAsInt >= 30 AND #theTypeAsInt <= 38
SET #returnValue = 0
ELSE
SET #returnValue = 1
ELSE
SET #returnValue = 1
RETURN #returnValue
END
GO
SELECT (SELECT COUNT(*)
FROM isErrorMismatch(LEFT(Type, 1),LEFT([Exception Code/Category],2))
As MismatchCount
FROM dbo.[All Service Ticket Data 2012_final]
Every record that makes the function return 1, I want to count. I am getting syntax errors in my FROM when I call the function. Anyone have any ideas? Thank you!
***UPDATE:
In order to get the count that make the function return 1:
SELECT COUNT(dbo.isErrorMismatch(LEFT(Type, 1), LEFT([Exception Code/Category],2))) As MismatchCount
FROM dbo.[All Service Ticket Data 2012_final]
WHERE dbo.isErrorMismatch(LEFT(Type, 1), LEFT([Exception Code/Category],2)) = 1
In order to get all of the records that make the function return 1:
SELECT Type, [Exception Code/Category],
dbo.isErrorMismatch(LEFT(Type, 1),LEFT([Exception Code/Category] ,2)) as Mismatch
FROM dbo.[All Service Ticket Data 2012_final]
WHERE dbo.isErrorMismatch(LEFT(Type, 1),LEFT([Exception Code/Category] ,2)) = 1

Scalar UDF, which in this case accepted two parameters and returned a single value.
Some of the areas where you can use a scalar UDF:
A column expression in a SELECT or GROUP BY
A search condition for a JOIN in a FROM clause
A search condition of a WHERE or HAVING clause
SELECT SUM(CAST(dbo.isErrorMismatch(LEFT(Type, 1), LEFT([Exception Code/Category],2)) AS int)) As MismatchCount
FROM dbo.[All Service Ticket Data 2012_final]

You are having an error because your function is not a table type or does not return a table and so you can NOT select from it. But nevertheless you can achieve it by doing this:
SELECT COUNT(*)
FROM dbo.[All Service Ticket Data 2012_final] a
INNER JOIN
(
SELECT isErrorMismatch(LEFT(Type, 1),LEFT([Exception Code/Category],2)) IsMatched, Your_PK_Column_or_Id
FROM dbo.[All Service Ticket Data 2012_final]
) x ON x.Your_PK_Column_or_Id = a.Your_PK_Column_or_Id
WHERE x.IsMatched = 1
I just want to add that if the value you passed a value to #theExCode that cannot be cast to an INT then there will be an exception in your query.

You need to end the CREATE FUNCTION with GO. Also, your SELECT subquery needs a closing parenthesis at the end.
(Your question was about the syntax errors).

Related

how to use declared variable to select data from another table in case when condition?

I made select query in which i want to select data based on condition.For this i declared one variable and set value of that variable in else part.I want to use that variable for further select in same else part how can i achieve this?Please Help
declare #stateid int
select CASE WHEN MstCustomerAddressInfo.StateId is null
THEN 24
ELSE set #stateid = MstCustomerAddressInfo.StateId
select mststate.statecode from mststate where MstState.StateId = #stateid
END AS StateCode
No, you can't have SET inside a CASE expression. Even you can't have multiple statements.
Same query you can write as following.
declare #stateid int
select CASE
WHEN MstCustomerAddressInfo.StateId is null THEN 24
ELSE
-- set #stateid = MstCustomerAddressInfo.StateId
(select mststate.statecode
from mststate
where MstState.StateId = MstCustomerAddressInfo.StateId)
END AS StateCode
from [Your_Table]

Choose multiple cases condition

I want to get multipule choises after then in case statment as
#value
select * from [dbo].[Currency_Tbl]
WHERE [Currency_Active_YN]=
CASE WHEN #value = 1 THEN
( 1 or 0)
ELSE
#Value = 0 then 0
END
it didn't accept the first line in col1 but accept the col2
how can I select multiple numbers after THEN?
You don't use case in where clauses. Use boolean logic
select * from [dbo].[Currency_Tbl]
WHERE (#value = 1 and [Currency_Active_YN] in (0,1))
OR (#value = 0 and [Currency_Active_YN] = 0)
You dont need a case to do what you're trying to do. Assuming Currency_Active_YN is a not null bit field the following logic should suffice.
select * from [dbo].[Currency_Tbl]
WHERE (#value=1 OR [Currency_Active_YN]=#Value)

Temp table has only one row inserted

Hi I have an SP in which i create a temporary table to store some values.
ALTER PROCEDURE [dbo].[test]
#id int,
#funds_limit money
AS
BEGIN
SET NOCOUNT ON;
DECLARE #threshold money;
CREATE TABLE #ConfigurationTemp
(id int,
name varchar(100) not null,
type varchar(100),
value varchar(100))
INSERT #ConfigurationTemp EXEC get_config #id, 'testType', null
select #threshold = value
from #ConfigurationTemp
where id=#id and name='testLimit'
print #threshold
IF (#funds_limit IS NOT NULL) AND (#threshold < #funds_limit)
BEGIN
DROP TABLE #ConfigurationTemp;
RETURN 1000;
END
select #threshold = value
from #ConfigurationTemp
where id=#id and name='testLimit1'
print #threshold
IF (#funds_limit IS NOT NULL) AND (#threshold < #funds_limit)
BEGIN
DROP TABLE #ConfigurationTemp;
RETURN 1001;
END
END
RETURN 0;
END
The temporary table have multiple rows.
eg:
1, fund_limit, testType, 10
2, fund_min_limit, testType, 20
I need to first validate the value for fund_limit (10) with the user input value (which will be an input parameter to the SP). If the validation fails, i return with an error code. If not, I go for the next check. i.e., fund_min_limit. I do the same with it and return a different error code. If no validation fails, i will return 0 which is considered to be a success.
In this case, I am getting same value for threshold always. i.e., the value of first row... 10.
How can I get the different threshold value from the temp table with respect to the name?
When you assign scalar variable with select - it may be not assigned (unchanged - may keep value from previous assignment) if this select returned zero rows. To ensure your variable changed it's value rewrite it as set expression.
So if you misspelled second threshold name you may be "getting" same #threshold value because second statement does not assign anything to your variable i.e. variable contains value from prior assignment (select). You may test it with additional variable for second threshold - it will be always NULL if i guessed the issue reason.
Also you are applying same #id filter which is a scalar variable. But your rows have different ids. So there is no chances right now to get any other threshold's value than for #id given.
set #threshold = (select t.value
from #ConfigurationTemp t
where t.name='testLimit')
print #threshold
IF #threshold < #funds_limit
RETURN 1000;
set #threshold = (select t.value
from #ConfigurationTemp t
where t.name='testLimit 2')
print #threshold
IF #threshold < #funds_limit
RETURN 1001;
If will succeed only when both arguments are NOT NULL.
One more approach:
declare
#threshold_a int,
#threshold_b int,
#threshold_c int
;with test as
(
select 'a' as name, 25 as value
union all
select 'b', 3
union all
select 'c', 100
union all
select 'd', -1
)
select
#threshold_a = case when t.name = 'a' then t.value else #threshold_a end,
#threshold_b = case when t.name = 'b' then t.value else #threshold_b end,
#threshold_c = case when t.name = 'c' then t.value else #threshold_c end
from test t
select
#threshold_a as [a],
#threshold_b as [b],
#threshold_c as [c]
GO
single select, several variables.
You have RETURN in your IF statment.
... RETURN 1000
and
... RETURN 1001
After insert a row the procedure end.
Maybe you want to assign a result to a variable
#return_Value = ''
#return_Value = #return_Value + '1000, '
....
#return_Value = #return_Value + '1001, '
RETURN #return_Value

SQL CASE wrong output

I have this weird encounter using CASE in sql 2014.
This is my query:
SELECT (CASE WHEN dbo.GetFunctionAge(C.Birthdate) = 0
THEN '' ELSE dbo.GetFunctionAge(C.Birthdate)
END) AS Age
,dbo.GetFunctionAge(C.Birthdate)
,c.Birthdate
FROM Client C
WHERE ClientID = '34d0d845-e3a6-4078-8936-953ff3378eac'
this is the output:
Here is the GetFunctionAge function if you might ask.
IF EXISTS (
SELECT *
FROM dbo.sysobjects
WHERE ID = OBJECT_ID(N'[dbo].[GetFunctionAge]') AND
xtype in (N'FN', N'IF', N'TF'))
DROP FUNCTION [dbo].[GetFunctionAge]
GO
CREATE FUNCTION [dbo].[GetFunctionAge](#BirthDate DATETIME)
RETURNS INT
AS
BEGIN
DECLARE #Age INT
IF(#BirthDate = '1753-01-01 00:00:00.000')
BEGIN
SET #Age = 0
END
ELSE
BEGIN
SET #Age = DATEDIFF(hour,#BirthDate,GETDATE())/8766
END
RETURN #Age
END
GO
Question:
Why is Column Age in my output is 0which should be ''?
I added (No column name) to show that its output is 0 so my expected output base from my case condition is '' not 0
I didn't receive any error regarding inconsistency of data so why is case behaving like that?
Thanks for those who could clarify this to me.
SELECT
(CASE
WHEN a.ageint = 0 THEN ''
ELSE cast(a.ageint as varchar(3))
END) AS Age
, a.ageint
, c.Birthdate
FROM Client as C
CROSS APPLY (
SELECT
ISNULL(dbo.GetFunctionAge(C.Birthdate), 0) AS ageint
) AS a
WHERE ClientID = '34d0d845-e3a6-4078-8936-953ff3378eac'
;
You can cast it into varchar so you can return ' '.
SELECT (CASE WHEN dbo.GetFunctionAge(C.Birthdate) = 0
THEN '' ELSE Cast(dbo.GetFunctionAge(C.Birthdate) as varchar(5))
END) AS Age
,dbo.GetFunctionAge(C.Birthdate)
,c.Birthdate
FROM Client C
WHERE ClientID = '34d0d845-e3a6-4078-8936-953ff3378eac'
But If you wish to remain your Age column in data type int.
You could just use NULL instead of ' '

SQL Stored Procedure set variables using SELECT

I have a stored procedure in SQL Server 2005 with multiple variables and I want to set the values of these variables using a select statement. All three variables come from a same table and there should be a way to set them using one select statement instead of the way I currently have as shown below. Please help me to figure it out.
DECLARE #currentTerm nvarchar(max)
DECLARE #termID int
DECLARE #endDate datetime
SET #currentTerm =
(
Select CurrentTerm from table1 where IsCurrent = 1
)
SET #termID =
(
Select TermID from table1 where IsCurrent = 1
)
SET #endDate =
(
Select EndDate from table1 where IsCurrent = 1
)
select #currentTerm = CurrentTerm, #termID = TermID, #endDate = EndDate
from table1
where IsCurrent = 1
One advantage your current approach does have is that it will raise an error if multiple rows are returned by the predicate. To reproduce that you can use.
SELECT #currentTerm = currentterm,
#termID = termid,
#endDate = enddate
FROM table1
WHERE iscurrent = 1
IF( ##ROWCOUNT <> 1 )
BEGIN
RAISERROR ('Unexpected number of matching rows',
16,
1)
RETURN
END