This might be a very simple select statement, here's my question.
I have a variable
DECLARE #A varchar(128) --declaring variable
SET #A = 'sus_123456_R5_20140506' --setting value
I want to find the value after 'sus_' and before 'R5'
Also, the value in between is not of fixed length. So the function has to be dynamic.
However it always have sus and _R5_date. That's constant.
SET #A = 'sus_129_R5_20150408
Thanks
Use SUBSTRING in combination with CHARINDEX:
SELECT SUBSTRING(#A,CHARINDEX('sus_',#A,0)+4,CHARINDEX('_R5',#A,0)-5)
You can try this once using SUBSTRING() and CHARINDEX() FUNCTION
DECLARE #A varchar(128) --declaring variable
SET #A = 'sus_123456_R5_20140506'
select substring(#A,charindex('_',#A)+1,charindex('r5',#A)- (2+charindex('_',#A)))
Results in: 123456
(OR) This one using LEFT(),RIGHT() and CHARINDEX() function.
DECLARE #A varchar(128)
SET #A = 'sus_129_R5_20150408'
select right(left(#A,charindex('R5',#A) - 2),charindex('_',#A) - 1)
Results in: 129
Read more about String Function
Related
I am trying to concatenate strings but it doesn't seem to work. Can somebody tell me what is wrong with the code below?
declare #x varchar = 'a';
SET #x += 's'
SET #x = #x + 'z'
SET #x = concat('x','y')
SELECT #x;
None of the above methods worked. I am getting the output as 'x'.
As per Aaron Bertrand's article here:
https://sqlblog.org/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length
...you should not be declaring VARCHAR without a length.
The problem is, if you don't define a length, SQL Server will assign
one for you, and it may not be as wide as you expect. In some
scenarios, it will be 1 (yes, that is the number one, not a typo), and
in others it will be 30.
The docs are quite clear in this as well:
varchar [ ( n | max ) ]
When n is not specified in a data definition or variable declaration
statement, the default length is 1. When n is not specified when using
the CAST and CONVERT functions, the default length is 30.
This will work fine:
declare #x varchar(10) = 'a';
SET #x += 's'
SET #x = #x + 'z'
SET #x = concat('x','y')
SELECT #x;
You need a length when you declare varchar(). Otherwise, it is only one character long:
declare #x varchar(255) = 'a';
Once the variable is big enough to store the value, the rest of the code should work.
You need to tell sql the length of your varchar. In most cases sql treat varchar as varchar(1)
declare #x varchar(10) = 'a';
SET #x += 's'
SET #x = #x + 'z'
SET #x = concat('x','y')
SELECT #x;
You need to declare your VARCHAR with a length, try changing it to VARCHAR(20) and see what happens.
Declaring VARCHAR without a length results in Length being 1.
The code below will work, remember you need to declare strings long enough to contain the result.
declare #a varchar(100)
declare #b varchar(100)
set #a = 'This should ';
set #b = 'work';
select #a + #b
If you have shorter strings like this:
declare #a varchar(4)
declare #b varchar(4)
set #a = 'This should ';
set #b = 'work';
select #a + #b
You'll end up with the result:
'Thiswork'
Consider the following T-SQL code snippet:
CREATE PROC dbo.SquareNum(#i INT OUTPUT)
AS
BEGIN
SET #i = #i * #i
--SELECT #i
END
GO
DECLARE #a INT = 3, #b INT = 5
EXEC dbo.SquareNum #a OUTPUT
EXEC dbo.SquareNum #b
SELECT #a AS ASQUARE, #b AS BSQUARE
GO
DROP PROC dbo.SquareNum
The result set is:
ASQUARE BSQUARE
----------- -----------
9 5
As can be seen, #b is not squared, b/c it was not passed-in as output parameter (no OUTPUT qualifier when passing in the parameter).
I would like to know if there is a way I could check within stored procedure body (dbo.SquareNum body in this case) to see if a parameter has indeed been passed in as an OUTPUT parameter?
------ THIS WILL GIVE YOU THE BOTH VALUE IN squared------
CREATE PROC dbo.SquareNum(#i INT OUTPUT)
AS
BEGIN
SET #i = #i * #i
--SELECT #i
END
GO
DECLARE #a INT = 3, #b INT = 5
EXEC dbo.SquareNum #a OUTPUT
EXEC dbo.SquareNum #b OUTPUT
SELECT #a AS ASQUARE, #b AS BSQUARE
GO
DROP PROC dbo.SquareNum
-----TO CHECK STORED PROCEDURE BODY-----
SELECT OBJECT_NAME(object_id),
OBJECT_DEFINITION(object_id)
FROM sys.procedures
WHERE OBJECT_DEFINITION(object_id) =(SP_NAME)
Actually, there is a very simple way!
Make the parameter optional by setting a default value (#Qty AS Money = 0 Below)
Then, pass a value OTHER THAN THE DEFAULT when calling the procedure. Then immediately test the value and if it is other than the default value you know the variable has been passed.
Create Procedure MyProcedure(#PN AS NVarchar(50), #Rev AS NVarchar(5), #Qty AS Money = 0 OUTPUT) AS BEGIN
DECLARE #QtyPassed AS Bit = 0
IF #Qty <> 0 SET #QtyPassed = 1
Of course that means the variable cannot be used for anything other than OUTPUT unless you have a default value that you know will never be used as an INPUT value.
You can do this by query to sys views:
select
p.name as proc_name,
par.name as parameter_name,
par.is_output
from sys.procedures p
inner join sys.parameters par on par.object_id=p.object_id
where p.name = 'SquareNum'
or check in Management Studio in database tree:
[database] -> Programmability -> Stored Procedures -> [procedure] -> Parameters
Maybe I'm wrong but I don't believe it's possible. OUTPUT is part of the stored procedure definition so you should know when a parameter is or not OUTPUT. There is no way to set it dynamically so I think it's pointless to determine by code when a parameter is output or not because you already know it.
If you are trying to write a dynamic code, Piotr Lasota's answer should drive you to the correct way to realize when a parameter is Output.
Use the following query to get the name of all the parameters and to check if it is a output parameter:
select name, is_output from sys.parameters
I've declared a variable in a stored procedure:
DECLARE #CurrentChunk NVARCHAR(250)
I would like to use the length of the variable, i.e. 250, later in my sp for computational purposes, and I want to keep my code as dry as possible.
Here's my code (assume #Narrative is a param to the SP):
DECLARE #ChunkSizeCharacters INT,
#NumChunks INT,
#LoopIndex INT,
#CurrentChunk NVARCHAR(250)
SET #ChunkSizeCharacters = 250 -- HERE'S WHERE I WANT THE LENGTH OF #CurrentChunk
SET #NumChunks = CEILING((LEN(#Narrative) * 1.0)/#ChunkSizeCharacters)
SET #LoopIndex = 0;
WHILE (#LoopIndex < #NumChunks)
BEGIN
SET #CurrentChunk = SUBSTRING(#Narrative,
((#LoopIndex * #ChunkSizeCharacters) + 1), #ChunkSizeCharacters)
INSERT INTO [dbo].[Chunks] ([Chunk]) VALUES (#CurrentChunk)
SET #LoopIndex = #LoopIndex + 1
END
Is there a way to ascertain the length of an NVARCHAR or VARCHAR variable definition (please read carefully -- I'm not looking for LEN())?
It seems the MaxLength variant property returns the value you're looking for.
DECLARE #Banana varchar(255) = 'This banana'
SELECT SQL_VARIANT_PROPERTY(#Banana, 'MaxLength')
Returns 255.
If you don't mind overwriting the variable (and if you do, you can assign it to a temp NVARCHAR(MAX)):
SELECT #CurrentChunk = REPLICATE(0, 8000);
SELECT #ChunkSizeCharacters = LEN(#CurrentChunk);
This trick does not and cannot work for NVARCHAR(MAX), but that's presumably no problem, given it's enormous maximum size.
Unfortunately T-SQL has nothing in the way of metadata properties for variables. Even determining the type of an expression is a chore.
Interestingly, the value returned by that SELECT SQL_VARIANT_PROPERTY statement doesn't select into a plain, predefined variable. In the end, I used:
DECLARE #Text VARCHAR(400), #TextLen INT
SELECT #TextLen = CAST(SQL_VARIANT_PROPERTY(ISNULL(#Text, ''), 'MaxLength') AS INT)
Works like a charm for me!
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)
i have a field called LastWebpage, in the Field it stores the webpage .asp pagename
I have to write a script where i just need to take the jl_AssessmentDirect.asp name instead of 4000_1_jl_AssessmentDirect.asp. How do i get rid of 4000_1_. Please help.
Thanks.
Here are a couple of ways to do this, I assume the data is not always the same, this is just to show you how the functions work
right or replace is my preferred method
DECLARE #v VARCHAR(100)
SELECT #v = '4000_1_jl_AssessmentDirect.asp'
SELECT REPLACE(#v,'4000_1_','')
or
DECLARE #v VARCHAR(100)
SELECT #v = '4000_1_jl_AssessmentDirect.asp'
DECLARE #r VARCHAR(100)
SELECT #r ='4000_1_'
--if you have spaces RTRIM and LTRIM everything
SELECT RIGHT(#v,LEN(#v) -LEN(#r))
If stuff changes, you can dump it in variables
DECLARE #v VARCHAR(100)
SELECT #v = '4000_1_jl_AssessmentDirect.asp'
DECLARE #r VARCHAR(100)
SELECT #r ='4000_1_'
SELECT REPLACE(#v,#r,'')
Ideally you want to update such columns to only have the URL and nothing else
"It depends"
If always "4000_1_", use REPLACE as per SQLMenace's answer.
If a fixed length of any string, use SUBSTRING. No need to work out LENGTH first
SUBSTRING(MyValue, 8, 8000)
If the right hand side is fixed length and the unwanted part is variable length, use RIGHT
If both sides are variable, you'll need something like
SUBSTRING(MyValue, PATINDEX('%[_]1[_]%', MyValue) + 3, 8000)
Edit:
If you always want "jl"...
SUBSTRING(MyValue, PATINDEX('%jl%', MyValue), 8000)
Besides all the suggestions here already you can use stuff.
declare #s varchar(100)
set #s = '4000_1_jl_AssessmentDirect.asp'
select stuff(#s, 1, 7, '')
Remove characters before jl
declare #s varchar(100)
set #s = '4000_1_jl_AssessmentDirect.asp'
select stuff(#s, 1, charindex('jl', #s)-1, '')