Hello i am trying to create a function in ms sql server that accepts an integer parameter and returns a varchar. I am however having some trouble implementing this and would really love some help with this:
CREATE FUNCTION GetCategory (#CategoryID int)
RETURNS int
AS
BEGIN
DECLARE #Category varchar(64)
#Category = (SELECT Category
FROM Categories
WHERE CategoryID = #CategoryID)
RETURN #Category
END
The code above is what i tried doing already. I get the following error upon execution:=:
Msg 102, Level 15, State 1, Procedure GetCategory, Line 7
Incorrect syntax near '#Category'.
Msg 137, Level 15, State 2, Procedure GetCategory, Line 11
Must declare the scalar variable "#Category".
If Column CategoryID is a Primary key in your table and you are 100% sure there will be only ONE Category with a particualr CategoryID then your code is safe, but if it isnt a primary key and you can possibly have multiple Categories with same CategoryID then I would suggest using SELECT TOP 1 in your select statement.
CREATE FUNCTION GetCategory (#CategoryID int)
RETURNS varchar(64) --<-- This needs to be the datatype you want to return
AS
BEGIN
DECLARE #Category varchar(64);
SELECT #Category = Category
FROM Categories
WHERE CategoryID = #CategoryID
RETURN #Category;
END
Calling Function
SELECT dbo.GetCategory (1);
You say RETURNS int when actually you return a varchar 64.
Also when asking a question and posting sample code of what doesn't work it helps if you say "what" doesn't work. (what error message you get etc).
Related
I have created a function named 'fname'.
/*
create function fname(#ss int)
returns int
with schemabinding
as
begin
return #ss
end
*/
object_id('fname')
Now I want to get its id using object_id function by specifying its name. SQL Server gives an error
Msg 102, Level 15, State 1, Line 11
Incorrect syntax near 'fname'.
Can anyone point what I am doing wrong? Thanks in advance.
You need to use the function under the SELECT statement
select object_id('fname')
I tried it and succeeded
create function fname(#ss int)
returns int
with schemabinding
as
begin
return #ss
end
go
select object_id('fname')
This what I have so far individually all for sections work fine, I just cant figure out how to combine them properly.
Table function and procedure
USE [MENUdb]
GO
CREATE Function [dbo].[func_GetMenuItemsForMenu]
(
#MENUID NVARCHAR (50)
)
RETURNS TABLE
AS
RETURN
(
SELECT MenuItem.MenuID,MenuItem.MenuItemID,MenuItem.MenuItemTitle FROM MenuItem,Menu
WHERE Menu.MenuID = #MENUID
AND MenuItem.MenuID = Menu.MenuID)
GO
USE [MENUdb]
GO
ALTER Procedure [dbo].[sp_GetMenuItemsForMenu]
(
#ENTER_MENUID int
)
AS
BEGIN
SELECT * FROM func_GetMenuItemsForMenu (#ENTER_MENUID)
END
Scalar function and procedure
USE [MENUdb]
ALTER FUNCTION [dbo].[func_GetMenuItemDescriptionForMenuItemID]
(
#MENUITEMID int
)
RETURNS nvarchar(MAX)
AS
BEGIN
RETURN
(
SELECT MenuItem.MenuItemTitle +' ' + MenuItem.MenuItemDescriptionText FROM MenuItem WHERE MenuItemID = #MENUITEMID
)
END
USE [MENUdb]
GO
ALTER Procedure [dbo].[sp_GetMenuItemDescriptionForMenuItemID]
(
#ENTER_MENUITEMID int
)
AS
BEGIN
SELECT dbo.func_GetMenuItemDescriptionForMenuItemID (#ENTER_MENUITEMID)
END
Individually they work fine exactly as they should besides the fact that I am not sure how to output if there are multiple rows that fit the input for the scalar
My main issue is that I can quite figure out how to get the result of the Table function specifically the MenuItemID column to work as the input of the Scalar function
what should happen is this, say there are 3 items on menu 1, I enter 1 in the initial execution and it returns the 3 items IDs and Names in table form, how do I pass the IDs in the MenuItemID column to the next function?
Coding is not my strong point so im probably missing something very simple...
I created a custom table type
Create type dbo.InsertPatient as table
(SSN Int,
LastUpdated Datetime,
PatientId varchar(50),
McdNo varchar(50),
mcrno varchar(50)
)
GO
I tried to declare an input parameter using this type
Create PROCEDURE [dbo].[proc_PatientDt_Insert]
(
#PatientTable InsertPatient READONLY,
#FacilityID int,
#IsDeleted bit = 0
)
AS
BEGIN
SET NOCOUNT OFF
DECLARE #Err int
IF(#IsDeleted = 1)
BEGIN
DELETE FROM [Patient]
WHERE LTRIM(RTRIM([Patientid])) = LTRIM(RTRIM(#PatientTable.PatientId))
AND FacilityID = #FacilityID
RETURN
END
SET #Err = ##Error
RETURN #Err
END
When I try to execute, I get this error
Msg 137, Level 16, State 1, Procedure proc_PatientDt_Insert, Line 18
Must declare the scalar variable "#PatientTable".
The error message is a little misleading, but it's because you're trying to use a Table Varaible as if it was a plain old scalar variable. Table variables work more or less like tables. While it's possible the variable will only have one row, it could have 100. You need to SELECT and/or JOIN from that variable. If you only ever expect to have 1 row, or want to take an arbitrary first row and ignore others, you could change
LTRIM(RTRIM([Patientid])) = LTRIM(RTRIM(#PatientTable.PatientId)) AND FacilityID=#FacilityID
to
LTRIM(RTRIM([Patientid])) = LTRIM(RTRIM(SELECT TOP 1 PatientId FROM #PatientTable)) AND FacilityID=#FacilityID
But you'd probably be best off doing:
DELETE p
FROM Patient p
INNER JOIN #PatientTable p2
ON LTRIM(RTRIM(p.PatientId) = LTRIM(RTRIM(p2.PatientId)
WHERE p.FacilityId = #FacilityId
Getting very annoyed with this simple query...
I need to add an offset to a varchar, if it's a number and do nothing is it is not.
For this reason I've created the following function in SQL-server.
I then extract the answer with:
select dbo.OffsetKPL("100",200)
However this does not work, I get the error
Msg 207, Level 16, State 1, Line 1
Invalid column name '100'.
The code for the function is as follows...
ALTER FUNCTION [dbo].[OffsetKPL](
#kpl varchar(20)
,#offset int = 0
)
RETURNS varchar(20)
AS
BEGIN
DECLARE #uitkomst varchar(20);
set #uitkomst = #kpl;
if not(#offset = 0) begin
if (IsNumeric(#uitkomst) = 1) begin
set #uitkomst = cast((cast(#kpl as int) + #offset) as varchar);
end;
end;
RETURN #uitkomst;
END
What's wrong? nowhere does it state that IsNumeric does not accept a variable.
Use single quotes for strings!
select dbo.OffsetKPL('100',200)
If you have QUOTED_IDENTIFIER on (the default) things in double quotes are expected to be object names.
isnumeric may not be what you need though as all kinds of unexpected things return 1 for this.
SELECT ISNUMERIC('$'), ISNUMERIC('.'),
ISNUMERIC('12d5'), ISNUMERIC(','), ISNUMERIC('1e1')
See IsNumeric() Broken? Only up to a point for some discussion on this point.
Why isn't my insert procedure returning the ID of the newly inserted row? AND, when calling this procedure, why do I have to supply a value for #EventId? That column is a PK with IDENTITY.
IF OBJECT_ID ( 'vjsql.EventsINSERT', 'P') IS NOT NULL
DROP PROCEDURE EventsINSERT
GO
CREATE PROCEDURE EventsINSERT
#EventId int OUTPUT,
#EventDate datetime,
#Title varchar(100),
#IsActive bit
AS
BEGIN
INSERT INTO EventCalendar ( EventDate, Title, IsActive)
VALUES ( #EventDate, #Title, #IsActive)
SELECT #EventId = SCOPE_IDENTITY()
END
How are you making a call to the stored procedure?
This SP is returning the value of EventID by means of using OUTPUT parameters.
i.e. In programming terms, this is a procedure (not a function) that accepts an OUTPUT parameter which will be set with the value during the execution of the stored procedure.
For this, you will have to pass the variable for #EventID. The value of which will be set within the procedure and you will be able to read the value of it, once the procedure has finished.
See the example code below.
DECLARE #NewEventID INT
EXEC EventsINSERT
#EventId = #NewEventID OUTPUT,
#EventDate = '08/04/09',
#Title = 'Hello World',
#IsActive = 0
SELECT #NewEventID
Try adding some statement terminators:
BEGIN
INSERT INTO EventCalendar ( EventDate, Title, IsActive)
VALUES ( #EventDate, #Title, #IsActive);
SELECT #EventId = SCOPE_IDENTITY();
END
AND, when calling this procedure, why do I have to supply a value for #EventId? That column is a PK with IDENTITY.
You don't, but you do need to supply a variable of type int (or compatible with int) for the output value to be put into.
You don't need to specify a value for the OUTPUT parameter, you need to specify which local variable the output gets put into:
By default, SQL Management Studio names the parameter and the variable the same, which can be confusing. Here's an example of your SP being called:
DECLARE #InsertedEventId int
EXEC [dbo].[EventsINSERT]
#EventId = #InsertedEventId OUTPUT,
#EventDate = N'2009-08-05',
#Title = N'Some event',
#IsActive = 1
-- Display ID as result set
SELECT #InsertedEventId
Just to clarify: your stored procedure is fine. I used it as-is.
Why isn't my insert procedure
returning the ID of the newly inserted
row?
Your code should work. Try in the console instead of
SELECT #EventId = SCOPE_IDENTITY()
doing
SELECT SCOPE_IDENTITY()
and view what happens. Is possible that you are calling it the wrong way. You should store the value of the OUTPUT variable in a variable in the scope where you call this SP.
when calling this procedure, why do I
have to supply a value for #EventId?
Because you have to supply a value for every parameter you have. It doesn't matter if is a real value, it will be discarded, but you must call the stored procedure with a variable in this parameter to catch the returned value.
I'm pretty rusty with tsql, but don't you need to explicitly select ##identity to get that row id? That's where i'd go digging as I think scope_identity() may not return a value in the context of a user function/procedure.