I would like to do create a SQL function like this (pseudocode):
function PeopleInCompanies(companyIds)
SELECT * from Person WHERE CompanyId IN (companyIds)
end function
and call it like this:
define companyIds = 1,2,3
select * from PeopleInCompanies(companyIds)
is it even possible?
You would need to use a table type parameter. Assuming that CompanyID is an int:
CREATE TYPE dbo.ints AS TABLE ([value] int);
GO
CREATE FUNCTION dbo.PeopleInCompanies (#CompanyID dbo.ints READONLY)
RETURNS TABLE
AS RETURN
SELECT P.* --This should be replaced by the columns you need.
FROM dbo.Person P
JOIN #CompanyID CI ON P.CompanyID = CI.[Value];
Then you would call the function using:
DECLARE #CompanyID dbo.ints;
INSERT INTO #CompanyID
VALUES (1),(2),(3);
SELECT *
FROM dbo.PeopleInCompanies(#CompanyID);
SQL Server does not support macro substitution. That said, you have the table type as Gordon and Larnu mentioned, or you can simply parse/split the delimited string
Just another option
Declare #companyIds varchar(max) = '1,2,3'
Select A.*
From Person A
Join string_split(#companyIds,',') B
on A.CompanyID = B.Value
I have been asked to created a Function to accept CustomerID and return CustomerName for the CustomerID, I m a new Student/Developer Please if the question is not clear let me know so i can add more details about it, but that is what I was exactly asked.
functions in SQL are of three types.ignoring rest CLR functions ...
create table test
(
id int,
name varchar(4)
)
insert into test
select 1,'abc'
union all
select 2,'cde'
1.Scalar function takes one value and return one value
now for the above table ,you can create scalar function like below
create function dbo.test
(
#id int
)
returns varchar(4)
as
begin
declare #name varchar(4)
select #name=name from test where id =#id
return #name
End
You invoke it like:
select dbo.test(1)
2.Inline table valued functions:takes a single input same like scalar functions and returns table
create function dbo.test
(
#id int
)
as
returns TABLE
(
select * from test where id=#id)
You invoke it like:
select * from dbo.test(1)
3.Multi table valued function:
create function dbo.test
(
#id int
)
returns
#test table
(
id int,
name varchar(4)
)
as
begin
insert into #test
select * from test where id =#id
return
end
You invoke it like:
select * from dbo.test(1)
Take any one of Itzik Ben Gan books and start learning SQL the way it should be learned
I have a function that gets the recipeid. I am creating another function that shows the average price with recipename. How do I use the first function within the second function?
This is what I have so far. As can be seen, I am using a join for RecipeID, but I want it to use the 1st function I have (let's call it function1) that gets the ID instead. How do I go about this?
CREATE FUNCTION AveragePriceforRecipe() RETURNS #PriceTable TABLE (
[Amount] smallmoney,
[RecipeName] nvarchar(75)) AS
BEGIN
INSERT INTO #PriceTable
SELECT AVG(Amount)
FROM Prices JOIN
RecipePrices ON Prices.PriceID = RecipePrices.PriceID JOIN
Recipes ON RecipePrices.RecipeID = Recipes.RecipeID
END
are you using ms sql server (t-sql)? if so, please try the code below:
given that function1 is:
CREATE FUNCTION function1(#RecipeName)
RETURNS INT
AS
BEGIN
DECLARE #RecipeID INT
SELECT #RecipeID = ID
FROM Recipes
WHERE RecipeName = #RecipeName
RETURN #RecipeID
END
getting the recipes price table using function1:
CREATE FUNCTION AveragePriceforRecipe (#Amount SMALLMONEY, #RecipeName NVARCHAR(75))
RETURNS #PriceTable TABLE
AS
BEGIN
INSERT INTO #PriceTable
SELECT AVG(Amount)
FROM Prices
JOIN RecipePrices ON Prices.PriceID = RecipePrices.PriceID
AND RecipePrices.RecipeID = function1(#RecipeName)
END
I have a table in which a column named data is of type varbinary . If I do a simple query
select * from tab where data = 1 then it works but if I do select * from tab where data = '1' then it does not return any row. The issue comes when I create a stored proc to retrieve data from this table and it converts the query and adds ' ' in the parameter when querying and so I am not able to retrieve any data. Can some one please tell me how to get around this issue.
Parameters
#ID INT = NULL
,#Data varchar(100) = NULL
CREATE TABLE #Results (
ID INT
,Data varchar(100)
)
BEGIN
INSERT #Results (
ID
,Data
)
SELECT
SK.ID
,SK.Data
FROM dbo.tab SK
where SK.ID = #ID And SK.data = #data
END
SELECT #TotalRows = COUNT(*)
FROM #Results
SELECT #TotalRows TotalRows
Now from the code when I execute this statement
oReader = ExecuteReader(oConn, CommandType.StoredProcedure, "Proc", New SqlParameter("#ID", Request.ID), _
New SqlParameter("#Data", Request.Data))
I see in SQL Profiler that it runs the query as 'data'
which does not return any rows
Thanks
Since you have said that you have written an SP, I think the inpput parameter is specified as NVARCHAR or VARCHAR
Below is one way of doing but i'm guessing that the column called data will only have integer values in the first solution.
DECLARE #X VARCHAR(5)
SET #X = '1 '
SELECT CAST(#X AS INT)
The above is only if the Data column specified above is Integer.
If the same is string (VARCHAR) you can write a User defined function to do the same.
CREATE FUNCTION dbo.TRIM(#string VARCHAR(8000))
RETURNS VARCHAR(8000)
BEGIN
RETURN LTRIM(RTRIM(#string))
END
SELECT dbo.TRIM('1 ')
I hope the above was useful, I did get the idea rather copied the function from here
http://blog.sqlauthority.com/2007/04/24/sql-server-trim-function-udf-trim/
I am getting an error when trying to get this table valued function up. I have an error when I try to modify it. It is
Incorrect syntax near the keyword 'Declare'.
However when I use this outside of the function it all works great. So I was just wondering is there something I am missing or how should I be doing this. Thanks.
ALTER FUNCTION [dbo].[XXX]( #i_contactkey int,
#v_scope varchar(15),
#i_entrykey int = null,
#i_staffcontactkey int = null,
#d_startdate datetime,
#d_today datetime)
RETURNS TABLE
AS begin
Declare #temp as table
(contactkey int, contactkey1 int, rolekey1 int,contactkey2 int, rolekey2 int, relationshipid int)
insert into #temp (contactkey , contactkey1 , rolekey1 ,contactkey2 , rolekey2 , relationshipid )
select contactkey , contactkey1 , rolekey1 ,contactkey2 , rolekey2 , relationshipid
from contact clcon
LEFT JOIN contactassociation ca on ca.contactkey2 = clcon.contactkey where ca.rolekey1 in (4,5,6)
and ca.relationshipid = 181
and ca.activeind = 1
and ca.associationkey = (select top 1 associationkey
from contactassociation
where contactkey2 = clcon.contactkey and activeind = 1
and relationshipid = 181
and rolekey1 in (4,5,6)
order by begindate desc)
SELECT
clcon.contactkey'ClientId',
clcon.Stat'ClientStatus',
ctacct.optiondesc'account',
ctlvl.optiondesc'levelid',
(clcon.lastname+', '+clcon.firstname)'ClientName',
clcon.firstname'ClientFirstName',
clcon.lastname'ClientLastName',
clcon.addressline1'address1',
clcon.addressline2'address2',
clcon.city'city',
dbo.getcnfgoption(81,clcon.stateid,'D')'state',
clcon.zipcode'zipcode',
clcon.mainphone'mainphone',
cgcon.contactkey'cgkey',(cgcon.firstname+' '+cgcon.lastname)'CGName',
cgcon.firstname'CGFirstName',
cgcon.lastname'CGLastName',
cgcon.addressline1'cgaddressline1',
cgcon.addressline2'cgaddressline2',
cgcon.city'cgcity',
dbo.getcnfgoption(81,cgcon.stateid,'D')'cgstate',
cgcon.zipcode'cgzipcode',
cgcon.mainphone'cgmainphone',
dbo.getClientAltCGKeys_JSON(clcon.contactkey,'J')'AltCGsJSON',
--dbo.getClientAltCGKeys(clcon.contactkey,'C')'AltCGNames',
--dbo.getClientAltCGKeys(clcon.contactkey,'L')'altcgnamekeyslast',
--dbo.getClientAltCGKeys(clcon.contactkey,'A')'altcgkeysaddress',
dbo.getClientEventCount(clcon.contactkey, 'M', #d_startdate, #d_today) 'MLOA',
dbo.getClientEventCount(clcon.contactkey, 'N', #d_startdate, #d_today) 'NMLOA',
dbo.getClientEventCount(clcon.contactkey, 'A', #d_startdate, #d_today) 'Alts',
dbo.getClientEventCount(clcon.contactkey, 'S', #d_startdate, #d_today ) 'Suspension',
dbo.getClientEventCountAnnual(clcon.contactkey, 'C') 'MissingNotes',
-- dbo.getContactVerificationStatus(clcon.contactkey, 'D')'clverification',
-- dbo.getContactVerificationStatus(cgcon.contactkey, 'D')'cgverification',
ed1.eventkey 'mdskey',
dbo.getCnfgTableOption(54,ed1.eventstatusid,'D')'mdsstatus',
ed1.ScheduledDate 'NextMDS',
ed2.eventkey 'pockey',
dbo.getCnfgTableOption(54,ed2.eventstatusid,'D')'pocstatus',
ed2.ScheduledDate 'NextPoC',
ed3.eventkey 'hvkey',
dbo.getCnfgTableOption(54,ed3.eventstatusid,'D')'hvsstatus',
ed3.ScheduledDate 'NextHV',
ed4.eventkey 'medlistkey',
dbo.getCnfgTableOption(54,ed4.eventstatusid,'D')'medstatus',
ed4.ScheduledDate 'NextMedList',
ed5.eventkey 'semikey',
dbo.getCnfgTableOption(54,ed5.eventstatusid,'D')'semistatus',
ed5.ScheduledDate 'NextSemi',
ed6.eventkey'placementkey',
ed6.startdate'placementstart',
ed6.enddate'placementend',
[dbo].[getClientCMName](clcon.contactkey)'cmname',
[dbo].[getClientRNName](clcon.contactkey)'rnname',
[dbo].[getClientCMKey](clcon.contactkey)'cmkey',
[dbo].[getClientRNKey](clcon.contactkey)'rnkey',
alertcount=(SELECT COUNT(eventalertkey) FROM veventalert WHERE alerttype='Alert' AND clientkey=clcon.contactkey AND viewedind=0 AND contactkey=COALESCE(#i_staffcontactkey,#i_contactkey)),
alertkey=(SELECT MAX(eventalertkey) FROM veventalert WHERE alerttype='Alert' AND clientkey=clcon.contactkey AND viewedind=0 AND contactkey=COALESCE(#i_staffcontactkey,#i_contactkey)),
msgcount=(SELECT COUNT(eventalertkey) FROM veventalert WHERE alerttype='Message' AND clientkey=clcon.contactkey AND viewedind=0 AND cgkey=cgcon.contactkey),
msgkey=(SELECT MAX(eventalertkey) FROM veventalert WHERE alerttype='Message' AND clientkey=clcon.contactkey AND viewedind=0 AND cgkey=cgcon.contactkey),
clcp.birthdate
FROM (select dbo.getcontactstatus(contactkey,'ts')'Stat',* from contact where dbo.getcontactstatus(contactkey,'ts') is not null ) clcon
INNER JOIN contactrole cr
ON (clcon.contactkey = cr.contactkey)
--Find caregiver contact info
LEFT JOIN contactassociation ca on ca.contactkey2 = clcon.contactkey and ca.rolekey1 in (4,5,6)
and ca.relationshipid = 181 and ca.activeind = 1
and ca.associationkey = (select max(associationkey)
from contactassociation
where contactkey2 = clcon.contactkey and activeind = 1
and relationshipid = 181
and rolekey1 in (4,5,6))
LEFT JOIN contact cgcon
ON cgcon.contactkey = ca.contactkey1 and cgcon.activeind = 1
LEFT JOIN contactbu cbu
ON (clcon.contactkey = cbu.contactkey)
/*Account/Lvl Information*/
LEFT JOIN contactprofile clcp
ON (clcon.contactkey=clcp.contactkey)
LEFT JOIN cnfgtableoption ctlvl
ON (clcp.svclevelid = ctlvl.tableoptionkey)
LEFT JOIN cnfgtableoption ctacct
ON (clcp.accountid = ctacct.tableoptionkey)
LEFT JOIN eventdefinition ed1 /* MDS */
ON (clcon.contactkey=ed1.contactkey AND ed1.eventkey=dbo.getContactEventByWftask(clcon.contactkey, 181, 'MINOPEN'))
LEFT JOIN eventdefinition ed2 /* POC */
ON (clcon.contactkey=ed2.contactkey AND ed2.eventkey=dbo.getContactEventByWftask(clcon.contactkey, 120, 'MINOPEN'))
LEFT JOIN eventdefinition ed3 /* HV */
ON (clcon.contactkey=ed3.contactkey AND ed3.eventkey=dbo.getContactEventByWftask(clcon.contactkey, 341, 'MINOPEN'))
LEFT JOIN eventdefinition ed4 /* MED */
ON (clcon.contactkey=ed4.contactkey AND ed4.eventkey=dbo.getContactEventByWftask(clcon.contactkey, 178, 'MINOPEN'))
LEFT JOIN eventdefinition ed5 /* SEMI */
ON (clcon.contactkey=ed5.contactkey AND ed5.eventkey=dbo.getContactEventByWftask(clcon.contactkey, 122, 'MINOPEN'))
LEFT JOIN eventdefinition ed6 /* Placement */
ON (clcon.contactkey=ed6.contactkey AND ed6.wftaskkey = 49
AND ed6.eventstatusid = 16
AND ed6.activeind = 1
AND ed6.enddate = (select MAX(enddate) from eventdefinition
where contactkey = clcon.contactkey and wftaskkey = 49
and activeind = 1
and eventstatusid = 16))
WHERE
--Contact info
cr.rolekey = 8
AND cbu.entrykey = #i_entrykey
--and dbo.getcontactstatus (clcon.contactkey,'TS') not in ('Closed','Discharged')
and clcon.Stat not in ('Closed')
and clcon.activeind=1
-- filter by branch entrykey (if param exists)
--order by clcon.lastname,clcon.firstname
When you're using multiple statements in a function and returning a table, i.e. a Table-Valued User-Defined Function, you need a certain syntax, something like:
CREATE FUNCTION dbo.MyFunction(#ID int)
RETURNS #Mytable TABLE
(
-- Columns returned by the function
ID int PRIMARY KEY NOT NULL,
-- (Other columns as required)
)
AS
BEGIN
--Various statements to populate #Mytable
RETURN; -- Returns #Mytable
END
See Table-Valued User-Defined Functions for more information.
If you have a function that just has RETURNS TABLE with no definition of the table being returned, this is an Inline User-Defined Function.
Inline user-defined functions are a subset of user-defined functions
that return a table data type. Inline functions can be used to achieve
the functionality of parameterized views.
See Inline User-Defined Functions.
The syntax for this is like:
CREATE FUNCTION dbo.MyFunction(#ID int)
RETURNS TABLE
AS
RETURN
(
SELECT *
FROM MyTable
WHERE ID = #ID
);
Here you don't define the table being returned and the body of the function can only be one SELECT statement.
At the moment your code is somewhere between the two; you need to get this to work as the first option, i.e. the Table-Valued User-Defined Function; start by defining the table being returned in the RETURNS clause and go from there.
You have invalid function declaration. When returning table you should specify variable name that will hold your table, so your header may look like:
ALTER FUNCTION [dbo].[XXX](.....)
RETURNS #temp TABLE (contactkey int, contactkey1 int, rolekey1 int,contactkey2 int, rolekey2 int, relationshipid int)
AS
begin
...
You need to define the table's columns in the RETURNS statement.