function in sql - sql

I made a relation of criminal cases in a police station.
CREATE TABLE C_CASE
(
Case_ID int,
Case_Details varchar(255),
Case_Status varchar(255),
Section_Of_Law varchar(255)
);
INSERT INTO C_CASE
VALUES(333,'Hit and Run','Pending','304(A)');
INSERT INTO C_CASE
VALUES(444,'Robbery','Closed','392');
INSERT INTO C_CASE
VALUES(555,'Extortion','Pending','384');
INSERT INTO C_CASE
VALUES(222,'Murder','Closed','302');
I created a function which will return the number of Cases which are pending.
but I get an error. The function is :
create function NumOfCases(#statustype varchar(255)) returns varchar(255)
as
begin
return
(
select count(Case_Status) from C_CASE where Case_Status=#statustype
)
end
QUERY:
select from dbo.NumOfCases('Pending');
I keep getting the error:
Msg 156, Level 15, State 1, Line 21
Incorrect syntax near the keyword 'from'.
Where am I going wrong?

First, you need to change the return type of your function from varchar to integer using RETURNS int as you are trying to return a count.
The way you should call the function from sql is like this
select db.NumOfCases('Pending') as YourCount

You have several issues here. You did not name your column in your function. Then in your query you didn't specify anything to select. Since your query is a scalar function you don't use FROM. I would suggest however that you don't want a scalar function at all . The performance of them is horrible. A inline table valued function would be far better. Something like this.
create function NumOfCases
(
#statustype varchar(255)
) returns table
as
return
select count(Case_Status) as StatusCount
from C_CASE
where Case_Status = #statustype
Then to use this you could do something like this.
Select StatusCount
from NumOfCases('Pending')
You might also consider normalizing the status values. I would suggest using a Status table to hold the text values of your statuses. Then you have just the StatusID in your Case table.

Since it is a count of something use Integer for your return type.
create function NumOfCases(#statustype varchar(255))
returns INT
as
begin
Declare #RtnValue INT;
select #RtnValue = count(Case_Status) from C_CASE where Case_Status=#statustype
return #RtnValue
end

Related

SQL Server 2016 - Variable showing NULL

We have a scalar function in our application as below
CREATE function dbo.SCMGetEnvProfileValueFn
(#HierarchyCode varchar(255), -- Usually the subsystem code
#Code varchar(50), -- The Code to find
#Default varchar(255) -- If not found, return this default
)
RETURNS varchar(255)
AS
BEGIN
DECLARE #Value as varchar(255)
SELECT #Value = (SELECT TOP(1) Value FROM HVCEnvProfile
WHERE HierarchyCode = #HierarchyCode
AND Code = #Code)
RETURN ISNULL (#Value, #Default)
END
We converted this function to Table function
CREATE FUNCTION SCMGetEnvProfileValueTblFn
(#HierarchyCode varchar(255), -- Usually the subsystem code
#Code varchar(50), -- The Code to find
#Default varchar(255) -- If not found, return this default
)
RETURNS TABLE
AS
RETURN
(SELECT TOP(1) ISNULL (Value, #Default) AS value
FROM HVCEnvProfile
WHERE HierarchyCode = #HierarchyCode AND Code = #Code)
Below 2 statements shows different output. We do not have a column in the table HVCEnvProfile for this entry. Why the variable #Value is showing NULL when there is no row in the table.
SELECT value
FROM dbo.SCMGetEnvProfileValueTblFn('Registration', 'AdmitDtmEffectsLocationHistory', 'TRUE')
SELECT dbo.SCMGetEnvProfileValueFn('Registration', 'AdmitDtmEffectsLocationHistory', 'TRUE')
If a query returns no rows, then no rows will be returned, wrapping an ISNULL won't change that. Example:
SELECT ISNULL(V.C,0)
FROM (VALUES(1),(2),(3),(4))V(C)
WHERE V.C = 5;
Notice this does not return 0, but nothing.
You need to wrap the entire query in an ISNULL.
CREATE FUNCTION SCMGetEnvProfileValueTblFn (#HierarchyCode varchar(255), -- Usually the subsystem code
#Code varchar(50), -- The Code to find
#Default varchar(255) -- If not found, return this default
)
RETURNS table
AS
RETURN
SELECT ISNULL((SELECT TOP (1) [Value]
FROM HVCEnvProfile
WHERE HierarchyCode = #HierarchyCode
AND Code = #Code
ORDER BY SomeColumn), #Default) AS [Value]; --Don' forgot to change the value of SomeColumn
Don't forget, as well, you need an ORDER BY when using a TOP unless you're "happy" with inconsistent results (which I doubt), so i have added one that you will need to amend.

Linked Table Valued Function Parameters (SQL Server)

I need to create a SQL Server TVF that takes a single param and then used that param to build the other required parameters. Is this even possible?
The error states incorrect syntax near 'LEFT'. Simple representation below.
CREATE FUNCTION TESTFUNCTION
(
-- Add the parameters for the function here
#PRM1 VARCHAR(2) = 'ABC',
#PRM2 VARCHAR(1) = LEFT(#PRM1,1)
)
RETURNS TABLE
AS
RETURN
(
-- Add the SELECT statement with parameter references here
SELECT #PRM2
)
GO
Thank You!
BEFORE EDIT MADE IN THE QUESTION :
You need only one parameters :
SELECT #PRM2 = LEFT(#PRM1, 1);
However, you need scaler function not table valued function :
CREATE FUNCTION TESTFUNCTION
(
-- Add the parameters for the function here
#PRM1 VARCHAR(2) = 'ABC'
)
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE #PRM2 VARCHAR(255)
SET #PRM2 = LEFT(#PRM1, 1)
RETURNS (#PRM2)
END
Note : Your #PRM1 will accept only two characters which are AB. So, define appropriate length.

SQL Server function returns no value

I might be overlooking something here or it could be the lack of coffee this am... I have a SQL Server function I'm trying to create and have it spit out results.
This is my code:
ALTER FUNCTION [dbo].[fn_top_forms] ()
RETURNS #topforms TABLE
(
-- Add the column definitions for the TABLE variable here
clicks varchar(50),
title varchar(150),
urlpath varchar(max)
)
AS
BEGIN
DECLARE #clicks as varchar(50)
DECLARE #title varchar(150)
DECLARE #urlpath varchar(max)
DECLARE #everyone_relevant as bit
IF #everyone_relevant = 1
BEGIN
INSERT INTO #topforms
SELECT TOP (10) clicks, title, url
FROM dbo.view_all_forms
ORDER BY clicks DESC
END
RETURN
END
My issue is that its not returning any values but I know in the view_all_forms, there is indeed data there. I'm using this in new query to return the results, it has the columns but no data. Any ideas?
Yup, looks like I just didnt have the thing set write... Note to self, DRINK MORE coffee in the am.

Returning or outputting a #tableVariable in SQL

Is it possible to return or output a #tableVariable in SQL Server?
For example for the following stored procedure, how do I return the #TSV table variable?
ALTER PROCEDURE MyStoredProdecure
#Parameter1 INT,
#Parameter2 INT
AS
BEGIN
DECLARE #TSV TABLE
(
Transition_Set_Variable_ID INT,
Passed BIT
)
INSERT INTO #TSV
{ some data }
END
You cannot do it directly. Table variables are valid for READONLY input.
If you have no other data being returned from the stored procedure, you can select from the #TSV at the end and have the caller capture the output, e.g.
ALTER PROCEDURE MyStoredProdecure
#Parameter1 INT,
#Parameter2 INT
AS
BEGIN
DECLARE #TSV TABLE
(
Transition_Set_Variable_ID INT,
Passed BIT
)
INSERT INTO #TSV
{ some data }
SELECT * FROM #TSV
END
Caller
DECLARE #outerTSV TABLE
(
Transition_Set_Variable_ID INT,
Passed BIT
);
insert into #outerTSV
exec MyStoredProdecure 1, 2;
Alternatively, if the SP is really as simple as you showed, turn it into a table valued function instead.
No, but you can write a table valued function that returns a table.
create function MyTVF
#Parameter1 INT,
#Parameter2 INT
returns #tsv table
(
Transition_Set_Variable_ID INT,
Passed BIT
)
AS
BEGIN
INSERT INTO #TSV
{ some data }
return
END
Table Valued Parameters can only be used for input only, not output.
Depending on what your end goal is, here are some options:
change the sproc to a table-valued function to return a TABLE, that can then be used inline in another statement
simply SELECT the data from the #TSV table var at the end of your sproc
return an XML OUTPUT parameter (get a grubby feeling suggesting this, but just to highlight one way to return multiple rows actually using an OUTPUT parameter)
If you go for a Table Valued Function, ideally create an inline one if it is simple as it looks in your case:
e.g.
CREATE FUNCTION dbo.Func()
RETURNS TABLE
AS
RETURN
(
SELECT Something
FROM Somewhere
WHERE x = 1
)

sql insert into table which uses newid in user defined function [duplicate]

I have to insert a fake column at the result of a query, which is the return value of a table-value function. This column data type must be unique-identifier. The best way (I think...) is to use newid() function. The problem is, I can't use newid() inside this type of function:
Invalid use of side-effecting or time-dependent operator in 'newid()' within a function.
here's a clever solution:
create view getNewID as select newid() as new_id
create function myfunction ()
returns uniqueidentifier
as begin
return (select new_id from getNewID)
end
that i can't take credit for. i found it here:
http://omnibuzz-sql.blogspot.com/2006/07/accessing-non-deterministic-functions.html
-don
You can pass NEWID() as a parameter to your function.
CREATE FUNCTION SOMEIDFUNCTION
(
#NEWID1 as varchar(36), #NEWID2 as varchar(36)
)
RETURNS varchar(18)
AS
BEGIN
-- Do something --
DECLARE #SFID varchar(18)
SELECT #SFID = 'DYN0000000' + LOWER(LEFT(#NEWID1,4)) + LEFT(#NEWID2,4)
RETURN #SFID
END
GO
Call the function like this;
SELECT dbo.SOMEIDFUNCTION(NewID(),NewID())
use it as a default instead
create table test(id uniqueidentifier default newsequentialid(),id2 int)
insert test(id2) values(1)
select * from test
NB I used newsequentialid() instead of newid() since newid() will cause pagesplits since it is not sequential, see here: Some Simple Code To Show The Difference Between Newid And Newsequentialid
You could use ROW_NUMBER function:
SELECT
(ROW_NUMBER() OVER (ORDER BY recordID) ) as RowNumber ,
recordID,
fieldBla1
FROM tableName
Find more information at http://msdn.microsoft.com/pt-br/library/ms186734.aspx