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.
Related
I'm still trying to learn an SQL, i made a mistakes but i already search on the internet about the if statements...
I tried to create a simple function to check if the parameter is match the condition..
I have 2 parameters, that will be inputted manually by the users, but i got an error saying
Msg 156, Level 15, State 1, Procedure ufn_calculatebonus, Line 4 [Batch Start Line 1] Incorrect syntax near the keyword 'IF'. Msg 178, Level 15, State 1, Procedure ufn_calculatebonus, Line 10 [Batch Start Line 1] A RETURN statement with a return value cannot be used in this context.
This is the code i've tried to create, i thought i make the IF condition right? After the IF , should have a BEGIN and statements, closing it with END. ??
CREATE FUNCTION Sales.ufn_calculatebonus (#CompanyRevenue int, #OptionalParameter varchar(60))
RETURNS TABLE
AS
IF #CompanyRevenue > 10
BEGIN
SELECT 'INPUT CANNOT BE BIGGER THAN 1000'
END
ELSE
BEGIN
RETURN
(
SELECT * FROM SALES.CUSTBALANCE2 where region=#OptionalParameter or name=#OptionalParameter
);
END
GO
There are 2 distinct types of T-SQL table-valued functions, inline TVF and multi-statement TVF. The body of an inline TVF consists of only of a RETURNS statement with a query specification (not to be confused with a RETURN statement).
Your attempt at a multi-statement table-valued function is invalid for the reasons below.
The body of a multi-statement TVF must be surrounded with BEGIN...END.
A table variable with the returned schema must be declared in the function header.
One cannot return query results with a RETURN statement. Instead, insert results into the table variable declared in the function header end specify RETURN at the end of the function to return the results.
Below is an example of the remediated code. Importantly, note the use of an explicit column list throughout. Don't SELECT * in production code.
CREATE OR ALTER FUNCTION dbo.ufn_calculatebonus (#CompanyRevenue int, #OptionalParameter varchar(60))
RETURNS #BalanceInfo TABLE (CustomerID int, Balance int, ErrorMessage varchar(100))
AS
BEGIN
IF #CompanyRevenue > 10
BEGIN
INSERT INTO #BalanceInfo (ErrorMessage) VALUES('INPUT CANNOT BE BIGGER THAN 1000');
END
ELSE
BEGIN
INSERT INTO #BalanceInfo (CustomerID, Balance) --note ErrorMessage is omitted and will be NULL
SELECT CustomerID, Balance FROM SALES.CUSTBALANCE2 where region=#OptionalParameter or name=#OptionalParameter;
END;
RETURN;
END
GO
A stored procedure is a better fit than a than user-defined function if you need to raise custom errors for parameter validation. Here's a stored procedure example:
CREATE OR ALTER PROCEDURE dbo.usp_calculatebonus (#CompanyRevenue int, #OptionalParameter varchar(60))
AS
IF #CompanyRevenue > 10
BEGIN
THROW 50000, 'INPUT CANNOT BE BIGGER THAN 1000', 16;
END;
SELECT CustomerID, Balance FROM SALES.CUSTBALANCE2 where region=#OptionalParameter or name=#OptionalParameter;
GO
I have a table with a bigint column that I'm attempting to get an insert working for. We've been having issues where data that can't be converted to a numeric comes in and the insert fails. This is mostly things like spaces or line returns in the data i.e. " 123", "1 365".
Since I don't have access to the software that is attempting to insert this bad data, I thought that creating an instead of trigger and using a function to strip out all non-numeric characters would fix the issue.
This is a basic idea of what the trigger is doing.
TRIGGER [dbo].[Delivery_Before_TRG]
ON [dbo].[Delivery]
instead of INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[Delivery]
(....,[pin],....)
select ....
,[dbo].[udf_GetNumericOnly](inserted.pin)
,....
from inserted;
END
And this is the udf_GetNumberOnly function.
FUNCTION [dbo].[udf_GetNumericOnly]
(
#Value varchar(500)
)
RETURNS bigint
AS
BEGIN
Declare
#Pos tinyint,
#Char char(1)
Set #Value = REPLACE(#Value, ' ', '') -- Strip all spaces
Set #Pos = LEN(#Value) -- Give some non-zero value
While #Pos > 0
Begin
Set #Pos = PATINDEX('%[^0-9]%', #Value) )
If #Pos > 0
Begin
Set #Char = SUBSTRING(#Value, #Pos, 1) -- Non numeric character
Set #Value = REPLACE(#Value, #Char, '')
End
End
Set #Value = RTrim(LTrim(#Value))
Return convert(bigint,#Value)
END
I can run the function and it will strip all non-numeric characters for anything that I pass it, however, when I attempt to run an insert statement into my table I get a Msg 8114, Level 16, State 5, Line 4
Error converting data type varchar to bigint. error.
From what I can tell the problem is something to do with sql server checking that the fields I'm attempting to to insert match the destination table column datatypes before my trigger gets a hold of the data to convert it. I know this because I had modified the trigger to insert a number directly into the pin field and would still get this error.
Additionally, I know it isn't the function failing because I can write an insert that will fail and then change that insert to call the function, and it will work.
--This fails
INSERT INTO (....,pin,...)
VALUES(....,'1a23',....)
--This works
INSERT INTO (....,pin,...)
VALUES(....,udf_GetNumericOnly('1a23'),....)
Yeah, the algebrizer looks at the data types in your query right after the parser makes sure you've written valid sql. The INSTEAD OF INSERT trigger fires for each row that would be inserted, which an invalid cast wouldn't be.
I have to convert int to varchar and need to take care about one more consideration.
For example:
1)My string length is always 10 characters.
(i.e. "0000000001")
Whenever I generated a new id, it has to increment (i.e. "0000000002")
When it reaches the 10th string will be "0000000010", etc...
I have no idea how to implement this.
trying as a first step.
--Declared variable to increment count
declare #CTR INT
--#LIPRequestID is integer this is what i have to add to my
declare #LIPRequestID int
select #LIPRequestID=0
declare #LIPRequestIDstring varchar(max)
select #ctr=0
WHILE #CTR<2
BEGIN
select #ctr=#ctr+1
select #LIPRequestID=#LIPRequestID+1
select #LIPRequestIDstring='00000000'+ CAST(#LIPRequestID AS VARCHAR(10)
print #LIPRequestIDstring
END
but it is throwing the following exception error:
Msg 102, Level 15, State 1, Line 14
Incorrect syntax near '#LIPRequestIDstring'.
can anybody suggest where I am going wrong?
Instead of concatenating the string literal 00000000 with the ID you should use RIGHT:
DECLARE #LIPRequestIDstring varchar(10);
DECLARE #nextLIPRequestID int;
SET #nextLIPRequestID = (SELECT MAX(LIPRequestID) FROM dbo.TableName) + 1;
SET #LIPRequestIDstring = RIGHT('0000000000'+ CONVERT(VARCHAR(10),#nextLIPRequestID),10)
Parenthesis missing in cast function, other things looks fine
select #LIPRequestIDstring='00000000'+ CAST(#LIPRequestID AS VARCHAR(10))--here
Instead of
CAST(#LIPRequestID AS VARCHAR(10)
use
CAST(#LIPRequestID AS VARCHAR(10))
Instead of RIGHT function, we can use REPLACE function. This will help you to implement your two requirements. The length of the ID also can be passed as parameter #IDLength.
DECLARE #CTR INT = 0
DECLARE #LIPRequestID INT = 0
DECLARE #IDLength INT = 8
DECLARE #LIPRequestIDstring VARCHAR(MAX)
WHILE (#CTR < 12)
BEGIN
SELECT #CTR += 1
SELECT #LIPRequestID += 1
PRINT REPLACE(STR(#LIPRequestID, #IDLength), SPACE(1), '0')
END
Yes, Right function really make sence, thanks to sql and stackoverflow.
declare #LIPRequestIDstring varchar(max)
select #LIPRequestID=#LIPRequestID+1
select #LIPRequestIDstring=RIGHT('0000000000'+ CONVERT(VARCHAR(10),#LIPRequestID),10)
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).
hello programmers i'm writing a TSQL in-line table function, actually im not good enough in sql, when i finished my code i've got this error "Incorrect syntax near 'BEGIN'." , anyone know the solution please give it to me.
by the way when i clicked double-click over the error msg it's selected the last "end"
create FUNCTION [dbo].[CheckLogin]
(
#un varchar(max),
#pw varchar(max)
)
RETURNS TABLE
AS
begin
declare #unexist int, #unpwmatch int, #uid bigint
declare #uisactivated bit , #uisdeleted bit
-----
set #unexist = (select COUNT(UserAccessInfo.UserId) FROM UsersAccessInfo
WHERE UserAccessInfo.UserName = #un OR UserAccessInfo.UserEmail = #un)
------
set #unpwmatch = (select count(usersaccessinfo.userid) from usersaccesinfo
WHERE (usersaccessinfo.UserName = #un) AND (usersaccessinfo.UserPassword = #pw) OR
(usersaccessinfo.UserEmail = #un) AND (usersaccessinfo.UserPassword = #pw))
------
set #uid =(select usersaccessinfo.userid from usersaccessinfo where
serAccessInfo.UserName = #un OR UserAccessInfo.UserEmail = #un)
------
if #uid <> Null
begin
set #uisactivated =(select usersaccessinfo.userisactivated from usersaccessinfo
where usersaccessinfo.userid=#uid)
end
------
if #uid <> null
begin
set #uisactivated =(select usersaccessinfo.userisactivated from usersaccessinfo
where usersaccessinfo.userid=#uid)
end
------
if #unexist = 0
begin
select dbo.getreportbyid('1004')
end;
else if #unpwmatch = 0
begin
select dbo.getreportbyid('1005')
end;
else if #uid<>0
begin
if #uisactivated =0
begin
select dbo.getreportbyid('1002')
end;
else if #uisdeleted = 1
begin
select dbo.getreportbyid('1003')
end;
end;
else
begin
select ('successful') as report
end;
return
end;
The problem is these lines:
...
RETURNS TABLE
AS
...
This is not valid syntax for any of the four types of user-defined functions.
Assuming that you are trying to define a multi-statement table-valued function, it should look like this:
...
RETURNS #YourTableName TABLE( <column-definitions>... )
AS
...
And then your function statements should be putting the function return data into that table before it executes the RETURN statement, which it also is not doing.
Your problem is that you are mixing the syntax of multi-statement table valued functions and inline table valued functions. For examples of each and some performance considerations check out my post here: http://sqlity.net/en/498/t-sql-tuesday-24-prox-n-funx/
In short, if you want to use multiple statements within a table valued function you have to declare a table variable after the RETURNS keyword and insert the rows you want to return in there in the function body. However, this type of function has serious performance implications and you should try hard to stay away from it.
Besides of that, you seem to have mismatching BEGINs and ENDs. As Barry said, "A little indentation would go a long way here" in helping you and others understand you code better.
You cannot have ; before the if command end. Also null checing is wrong. For ex;
if #uid <> null -- (1) note: should be if #uid is not null
Begin
-- query
End; --(2)-Note: this is wrong
Else
Begin
--Query
End