Why does SQL Server think this function is non-deterministic?
CREATE FUNCTION [Util].[BuildStreetFullName]
(
#StreetNumber VARCHAR(20),
#StreetDir VARCHAR(2),
#StreetName VARCHAR(50) ,
#StreetType VARCHAR(4) ,
#StreetPostDir VARCHAR(2)
)
RETURNS VarChar(100)
AS
BEGIN
SET #StreetNumber = NULLIF( Util.Trim(#StreetNumber ), '');
SET #StreetDir = NULLIF( Util.Trim(#StreetDir ), '');
SET #StreetName = NULLIF( Util.Trim(#StreetName ), '');
SET #StreetType = NULLIF( Util.Trim(#StreetType ), '');
SET #StreetPostDir = NULLIF( Util.Trim(#StreetPostDir ), '');
DECLARE #Result VarChar(100) = #StreetNumber;
IF #StreetDir IS NOT NULL BEGIN
IF #Result IS NOT NULL
SET #Result = #Result + ' ' + #StreetDir;
ELSE
SET #Result = #StreetDir;
END
IF #StreetName IS NOT NULL BEGIN
IF #Result IS NOT NULL
SET #Result = #Result + ' ' + #StreetName;
ELSE
SET #Result = #StreetName;
END
IF #StreetType IS NOT NULL BEGIN
IF #Result IS NOT NULL
SET #Result = #Result + ' ' + #StreetType;
ELSE
SET #Result = #StreetType;
END
IF #StreetPostDir IS NOT NULL BEGIN
IF #Result IS NOT NULL
SET #Result = #Result + ' ' + #StreetPostDir;
ELSE
SET #Result = #StreetPostDir;
END
RETURN NULLIF(#Result, '');
END
CREATE FUNCTION [Util].[Trim]
(
#value nVarChar(max)
)
RETURNS nVarChar(max)
AS
BEGIN
RETURN LTrim(RTrim(#value))
END
1) You could create both function WITH SCHEMABINDING:
ALTER FUNCTION dbo.[Trim]
(
#value nVarChar(max)
)
RETURNS nVarChar(max)
WITH SCHEMABINDING
AS
...
and
ALTER FUNCTION dbo.[BuildStreetFullName]
(
#StreetNumber VARCHAR(20),
#StreetDir VARCHAR(2),
#StreetName VARCHAR(50) ,
#StreetType VARCHAR(4) ,
#StreetPostDir VARCHAR(2)
)
RETURNS VarChar(100)
WITH SCHEMABINDING
AS
...
This will force SQL Server to check if these function are deterministic or not.
SELECT OBJECTPROPERTY( OBJECT_ID(N'dbo.[BuildStreetFullName]') , 'IsDeterministic' ) AS IsDeterministic
Output:
IsDeterministic
---------------
1
2) Please don't use != NULL operator to check for NOT NULL. Use IS NOT NULL. At this moment ANSI_NULLS OFF is deprecated and a a future version of SQL Server will allow only ANSI_NULLS ON.
3) Scalar functions can be a nightmare from performance point of view. I would rewrite those functions as inline table valued functions.
Related
I have tried so many times but could not find the exact query yet.
The one I made works in few string but doesn't work in another(It is uncertain).
What i want is the word which has '.' in it like "abcde sfjhjk.dkjb sajb njdhf", what i want is "sfjhjk.dkjb" as result . This is just an example.
The query returns all letters in some cases while truncates few digits in other cases. You can check by providing different values.
I tried below :
This doesn't work:
DECLARE #QUERY VARCHAR(MAX)='
renewreque0_.amount AS AMOUNT48_,
renewreque0_.charge_type AS CHARGE3_48_,
renewreque0_.commission_rate AS COMMISSION4_48_
'
SET NOCOUNT ON;
DECLARE #TABLENAME TABLE(TABLE_NAME VARCHAR(MAX),ALIAS VARCHAR(MAX))
DECLARE #COLUMNS_JOIN TABLE(COL VARCHAR(MAX),COLUMN_NAME VARCHAR(MAX),ALIAS VARCHAR(MAX))
DECLARE #NAME VARCHAR(MAX),#ALIAS VARCHAR(MAX),#J_QUERY VARCHAR(MAX),#W_QUERY VARCHAR(MAX)
DECLARE #WHERE_JOIN TABLE(COL VARCHAR(MAX),COLUMN_NAME VARCHAR(MAX),ALIAS VARCHAR(MAX))
WHILE CHARINDEX('.',#QUERY)>1
BEGIN
SET #NAME = REVERSE( SUBSTRING(REVERSE(#QUERY),CHARINDEX('.',REVERSE(#QUERY))+1,CHARINDEX(' ',#QUERY)) )
SET #ALIAS= REVERSE(LEFT(REVERSE(#QUERY),CHARINDEX('.',REVERSE(#QUERY))))
SET #ALIAS=LEFT(#ALIAS,CHARINDEX(' ',#ALIAS))
SET #NAME=LTRIM(RTRIM(#NAME))
SET #ALIAS=LTRIM(RTRIM(#ALIAS))
INSERT INTO #COLUMNS_JOIN SELECT #NAME+#ALIAS,#NAME,REVERSE(LEFT(REVERSE(#ALIAS),LEN(#ALIAS)-1))
SET #QUERY=REPLACE(#QUERY,#NAME+#ALIAS,'')
END
SELECT * FROM #COLUMNS_JOIN
This works:
DECLARE #QUERY VARCHAR(MAX)='
AND t8_.username LIKE ?
AND t4_.branch_id = ?
AND t1_.account_no = ?
AND t0_.remarks = ?
AND t0_.collect_from = ?
'
SET NOCOUNT ON;
DECLARE #TABLENAME TABLE(TABLE_NAME VARCHAR(MAX),ALIAS VARCHAR(MAX))
DECLARE #COLUMNS_JOIN TABLE(COL VARCHAR(MAX),COLUMN_NAME VARCHAR(MAX),ALIAS VARCHAR(MAX))
DECLARE #NAME VARCHAR(MAX),#ALIAS VARCHAR(MAX),#J_QUERY VARCHAR(MAX),#W_QUERY VARCHAR(MAX)
DECLARE #WHERE_JOIN TABLE(COL VARCHAR(MAX),COLUMN_NAME VARCHAR(MAX),ALIAS VARCHAR(MAX))
WHILE CHARINDEX('.',#QUERY)>1
BEGIN
SET #NAME = REVERSE( SUBSTRING(REVERSE(#QUERY),CHARINDEX('.',REVERSE(#QUERY))+1,CHARINDEX(' ',#QUERY)) )
SET #ALIAS= REVERSE(LEFT(REVERSE(#QUERY),CHARINDEX('.',REVERSE(#QUERY))))
SET #ALIAS=LEFT(#ALIAS,CHARINDEX(' ',#ALIAS))
SET #NAME=LTRIM(RTRIM(#NAME))
SET #ALIAS=LTRIM(RTRIM(#ALIAS))
INSERT INTO #COLUMNS_JOIN SELECT #NAME+#ALIAS,#NAME,REVERSE(LEFT(REVERSE(#ALIAS),LEN(#ALIAS)-1))
SET #QUERY=REPLACE(#QUERY,#NAME+#ALIAS,'')
END
SELECT * FROM #COLUMNS_JOIN
Can anybody please help.
I would first use an SplitString function (passing a blank space as delimiter), which returns as rows each word on a string, and then filter it to return just the words having a dot.
SQL Server 2016 already has one https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql and on older SQL Servers you can build your own : Splitting the string in sql server
set #SQLStr varchar(512) = 'abcde sfjhjk.dkjb sajb njdhf';
select value from string_split(#SQLStr, ' ')
where charindex('.', value) > 0
Alright just for fun
declare #str nvarchar(100) = 'abcde sfjhjk.dkjb sajb njdhf',
#pointIndex int
SET #pointIndex = (SELECT CHARINDEX('.',#str) )
SELECT RTRIM(LTRIM(SUBSTRING(#str, #pointIndex - CHARINDEX(' ',REVERSE(LEFT(#str,#pointIndex))) +1,CHARINDEX(' ',REVERSE(LEFT(#str,#pointIndex)))) -- left side
+SUBSTRING(#str,#pointIndex +1, CHARINDEX( ' ', SUBSTRING(#str,#pointIndex,len(#str) - #pointIndex) ) -1 )))
Needless to say i would not recommend this option because it is really hard to maintain. As Marc said your best option here is to split your string for blanks and find the ones with a '.'
Now if you dont have SQLServer 2016 here is a split function for you :
CREATE function [dbo].[Split]
(
#string nvarchar(max),
#delimiter nvarchar(20)
)
returns #table table
(
[Value] nvarchar(max)
)
begin
declare #nextString nvarchar(max)
declare #pos int, #nextPos int
set #nextString = ''
set #string = #string + #delimiter
set #pos = charindex(#delimiter, #string)
set #nextPos = 1
while (#pos <> 0)
begin
set #nextString = substring(#string, 1, #pos - 1)
insert into #table
(
[Value]
)
values
(
#nextString
)
set #string = substring(#string, #pos + len(#delimiter), len(#string))
set #nextPos = #pos
set #pos = charindex(#delimiter, #string)
end
return
end
And use it as such :
SELECT * FROM dbo.Split(REPLACE(#str,' ','/'),'/')
WHERE charindex('.', value) > 0
Note that i replace blanks by another value.
I'm trying to create a Stored Procedure that generates a load of SQL dynamically. I'm trying to prevent string injection by using the sp_executesql to pass all of the parameters into the query. The query seems to execute fine but I have two issues. Firstly when I execute using my Alias name which uses the pattern xx\xxxxx it throws an error saying there is an error near the first two letters of the Alias. I think this is due to the NVARCHAR type but not entirely sure how to handle the \ in this. Secondly, and more importantly, the overall procedure returns nothing. It tells me that it has executed fine but I don't get my table of results as expected.
I've omitted the statements to generate the parameters for brevity (These work fine if I generate the whole string and Run EXEC string
I'm also wary of using global temp tables as this will be run in a multi-user environment
Updated with full code
DECLARE #IDType NVARCHAR(255) = NULL
DECLARE #Customer NVARCHAR(MAX) = NULL
DECLARE #IdentifiedBy NVARCHAR(255) = NULL
DECLARE #ImpactArea NVARCHAR(MAX) = NULL
DECLARE #Gateway NVARCHAR(255) = NULL
DECLARE #ProbabilityRating NVARCHAR(255) = NULL
DECLARE #ImpactRating NVARCHAR(255) = NULL
DECLARE #CostRevenue NVARCHAR(255) = NULL
DECLARE #Status NVARCHAR(255) = NULL
DECLARE #Keywords NVARCHAR(MAX) = NULL
DECLARE #govOwner NVARCHAR(255) = NULL
DECLARE #Alias VARCHAR(50)
DECLARE #Role NVARCHAR(255)
DECLARE #SQL NVARCHAR(MAX)
DECLARE #Where NVARCHAR(MAX) = ''
DECLARE #SQLOrder NVARCHAR(MAX)
SET #Alias = SUSER_SNAME()
SET #Role =(SELECT [Role] FROM [FB].[Users] WHERE [Alias] = #Alias)
IF #IDType IS NOT NULL
BEGIN
IF #IDType = 'Blank'
SET #Where += ' AND IDType = NULL OR IDType = '''''
ELSE IF #IDType != 'All'
SET #Where += ' AND IDType = #IDType'
END
IF #Customer IS NOT NULL
BEGIN
IF #Customer = 'Blank'
SET #Where += ' AND Customer = NULL OR Customer = '''''
ELSE IF #Customer != 'All'
SET #Where += ' AND Customer = #Customer'
END
IF #IdentifiedBy IS NOT NULL
BEGIN
IF #IdentifiedBy = 'Blank'
SET #Where += ' AND IdentifiedBy = NULL OR IdentifiedBy = '''''
ELSE IF #IdentifiedBy != 'All'
SET #Where += ' AND IdentifiedBy = (SELECT FB.Alias(#IdentifiedBy))'
END
IF #ImpactArea IS NOT NULL
BEGIN
IF #ImpactArea = 'Blank'
SET #Where += ' AND ImpactArea = NULL OR ImpactArea = '''''
ELSE IF #ImpactArea != 'All'
SET #Where += ' AND ImpactArea = #ImpactArea'
END
IF #Gateway IS NOT NULL
BEGIN
IF #Gateway = 'Blank'
SET #Where += ' AND Gateway = NULL OR Gateway = '''''
ELSE IF #Gateway != 'All'
SET #Where += ' AND Gateway = #Gateway'
END
IF #ProbabilityRating IS NOT NULL
BEGIN
IF #ProbabilityRating = 'Blank'
SET #Where += ' AND ProbabilityRating = NULL OR ProbabilityRating = '''''
ELSE IF #ProbabilityRating != 'All'
SET #Where += ' AND ProbabilityRating = #ProbabilityRating'
END
IF #ImpactRating IS NOT NULL
BEGIN
IF #ImpactRating = 'Blank'
SET #Where += ' AND ImpactRating = NULL OR ImpactRating = '''''
ELSE IF #ImpactRating != 'All'
SET #Where += ' AND ImpactRating = #ImpactRating'
END
IF #CostRevenue IS NOT NULL
BEGIN
IF #CostRevenue = 'Blank'
SET #Where += ' AND CostRevenue = NULL OR CostRevenue = '''''
ELSE IF #CostRevenue != 'All'
SET #Where += ' AND CostRevenue = #CostRevenue'
END
IF #Status IS NOT NULL
BEGIN
IF #Status = 'Blank'
SET #Where += ' AND Status = NULL OR Status = '''''
ELSE IF #Status != 'All'
SET #Where += ' AND Status = #Status'
END
IF #Keywords IS NOT NULL
IF #govOwner IS NOT NULL
BEGIN
IF #govOwner = 'Blank'
SET #Where += ' AND govOwner = NULL OR govOwner = '''''
ELSE IF #govOwner != 'All'
SET #Where += ' AND govOwner = (SELECT FB.Alias(#govOwner))'
END
CREATE TABLE #tmp (
ID int
,FeedbackType varchar(255)
,ImpactArea varchar(255)
,CreatedDate varchar(11)
,Customer varchar(255)
,IdentifiedBy varchar(255)
,CriticalityRating varchar(255)
,govOwner varchar(255)
,Status varchar(255)
)
SET #SQL = 'SELECT
fb.ID
,FeedbackType
,ImpactArea
,CONVERT(VARCHAR(11), CreatedDate, 3) AS CreatedDate
,Customer
,IdentifiedBy
,CriticalityRating
,govOwner
,Status
INTO #tmp
FROM [FB].[Feedback] fb
INNER JOIN (SELECT
ID
,MAX(Version) AS MaxVer
FROM FB.Feedback
GROUP BY ID
) mv ON fb.ID = mv.ID AND fb.Version = mv.MaxVer'
SET #SQLOrder = ' ORDER BY [ID] DESC'
IF #Where IS NOT NULL
SET #Where = ' WHERE ' + (SELECT STUFF(#Where,1 , 4, '')) + ' '
IF (#Role != 'Governance Board' AND #Role != 'Admin')
BEGIN
IF #Where IS NOT NULL
SET #Where += ' AND [Author] = #Alias OR [IdentifiedBy] = #Alias'
ELSE
SET #Where = ' WHERE [Author] = #Alias OR [IdentifiedBy] = #Alias'
END
SET #SQL += #Where + #SQLOrder
EXECUTE SP_ExecuteSQL #SQL
,#Alias = #Alias
,#Customer = #Customer
,#IdentifiedBy = #IdentifiedBy
,#ImpactArea = #ImpactArea
,#Gateway = #Gateway
,#ProbabilityRating = #ProbabilityRating
,#ImpactRating = #ImpactRating
,#CostRevenue = #CostRevenue
,#Status = #Status
,#Keywords = #Keywords
,#govOwner = #govOwner
SELECT * FROM #tmp
DROP TABLE #tmp
Change #SQL by removing the line
INTO #tmp
Then above EXECUTE SP_ExecuteSQL add the line
INSERT INTO #tmp
This will change your EXECUTE to a select statement, and then insert what is selected into your temp table, all in this session.
The error you're getting about the Alias parameter is because you're actually missing a bit. sp_executesql requires #params when using parameters, which defines the parameters you are using.
From the documentation:
-- Syntax for SQL Server, Azure SQL Database, Azure SQL Data Warehouse, Parallel Data Warehouse
sp_executesql [ #stmt = ] statement
[
{ , [ #params = ] N'#parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' }
{ , [ #param1 = ] 'value1' [ ,...n ] }
]
and
[ #params= ] N'#parameter_namedata_type [ ,... n ] '
Is one string that contains the definitions of all parameters that have been embedded in #stmt. The string must be either a Unicode constant or a Unicode variable. Each parameter definition consists of a parameter name and a data type. n is a placeholder that indicates additional parameter definitions. Every parameter specified in #stmtmust be defined in #params. If the Transact-SQL statement or batch in #stmt does not contain parameters, #params is not required. The default value for this parameter is NULL.
In your case this will be as follows:
DECLARE #params NVARCHAR(300) = N'#Alias VARCHAR(50), #Customer NVARCHAR(MAX), #IdentifiedBy NVARCHAR(255), #ImpactArea NVARCHAR(MAX),#Gateway NVARCHAR(255),#ProbabilityRating NVARCHAR(255), #ImpactRating NVARCHAR(255), #CostRevenue NVARCHAR(255), #Status NVARCHAR(255), #Keywords NVARCHAR(MAX), #govOwner NVARCHAR(255)';
And then use it as follows:
EXECUTE SP_ExecuteSQL #SQL, #params
,#Alias = #Alias
etc, etc
So you have to define your variables for the stored procedue, which you have done, but also for the dynamic sql you are running, which is the #params.
You must pass params definition to sp_executesql as shown below:
DECLARE #p NVARCHAR(MAX) = 'test';
SET #SQL = 'select #p';
EXECUTE SP_ExecuteSQL #SQL, N'#p NVARCHAR(MAX)', #p = #p;
Use #tbl instead of #tbl, remove ,#tbl = #tbl OUTPUT. Don't use SELECT INTO statement. Local temporary tables are visible in the current session, includes code in called procedures and nested dynamic SQL.
I am running into a problem getting my recursive script to find the current row from a table variable. I have verified that there is data in the table variable. That part is working great, however the next part of my script keeps hitting my else statement. It worked great with temp tables but I am trying to get this into a function so I can call it easier with other scripts.
BEGIN
DECLARE #totalrows INT
DECLARE #currentrow INT = 1
DECLARE #tempTable TABLE (value VARCHAR(255), ID INT)
SELECT * Into #temp FROM dbo.fn_split((SELECT TOP (1) address_full FROM sde.gis.BUSINESS), ' ')
ALTER TABLE #temp
ADD ID INT IDENTITY
INSERT into #tempTable ( value, ID )
SELECT *
FROM #temp
SELECT * FROM #tempTable
DECLARE #address_no MONEY
DECLARE #pre_dir VARCHAR(2)
DECLARE #street_name VARCHAR(45)
DECLARE #suffix VARCHAR(20)
WHILE ( #currentrow <= #totalrows )
BEGIN
DECLARE #cur_value VARCHAR(50)
SELECT #cur_value = value
FROM #tempTable
WHERE id = #currentrow
PRINT 'Working on ' + #cur_value
IF ( #currentrow = 1 )
BEGIN
IF ( ISNUMERIC(#cur_value) = 1 )
SET #address_no = CAST(#cur_value AS MONEY)
ELSE
RETURN
END
IF ( #currentrow = 2 ) -- Is this a direciton
BEGIN
IF EXISTS ( SELECT 1
FROM mead.dbo.street_direction
WHERE street_direction = #cur_value )
BEGIN
SET #pre_dir = #cur_value
END
ELSE
BEGIN
SET #street_name = #cur_value
END
END
IF ( #currentrow > 2 ) -- Is this a direciton
BEGIN
IF EXISTS ( SELECT 1
FROM mead.dbo.street_type
WHERE street_type = #cur_value )
BEGIN
SET #suffix = #cur_value
END
ELSE
BEGIN
IF ( #street_name IS NULL )
SET #street_name = #cur_value
ELSE
SET #street_name = #street_name + ' ' + #cur_value
END
END
SET #currentrow = #currentrow + 1
END
END
SELECT #address_no ,
#pre_dir ,
#street_name ,
#suffix
DROP TABLE #temp
Answered my own question. Forgot to set my totalrows = ##rowcount.
I am trying to create a dynamic query in SQL Server.
Input: #value= abc,def,en,
Output: MAX(abc) as abc, MAX(def) as def, MAX(en) as en
My efforts so far took me no where.
With CONVERT() and REPLACE() I achieved a bit but finding it difficult. Need help!
Try this:
declare #value varchar(50) = 'abc,def,en'
declare #result varchar(100) = ''
select #result = replace(#value,'abc', 'MAX(''abc'') as abc')
select #result = replace(#result,'def', 'MAX(''def'') as def')
select #result = replace(#result,'en', 'MAX(''en'') as en')
select #result
You can also do the replacements in one line by nesting the expressions.
EDIT: If you have variable values in #value, you can take the below approach:
Use a splitter function to get the individual values in the string as a list. You can take a look at this article for implementations.
Insert this list to a temp table.
Update the temp table as shown above.
Concatenate the values into a single string using STUFF like so:
select stuff((select ',' + val from #temp for xml path('')),1,1,'')
Try this:
DECLARE #Value VARCHAR(200) = 'abc,def,en'
DECLARE #Template VARCHAR(100) = 'MAX(''##'') as ##'
DECLARE #Result VARCHAR(1000) = ''
DECLARE #Data VARCHAR(100) = ''
WHILE LEN(#Value) > 0
BEGIN
SET #Data = REPLACE(LEFT(#Value, ISNULL(NULLIF(CHARINDEX(',', #Value),0), LEN(#Value))),',','')
SET #Result = #Result + REPLACE(#Template, '##', #Data)
IF CHARINDEX(',', #Value) > 0
BEGIN
SET #Result = #Result + ','
SET #Value = REPLACE(#Value,#Data + ',','')
END
ELSE
SET #Value = REPLACE(#Value,#Data,'')
END
SELECT #Result
Have a look at SQL User Defined Function to Parse a Delimited String
So you can do like
Declare #Value varchar(200) = 'abc,def,en'
Declare #Item varchar(20) = null
declare #Str varchar(1000)=''
WHILE LEN(#Value) > 0
BEGIN
IF PATINDEX('%,%',#Value) > 0
BEGIN
SET #Item = SUBSTRING(#Value, 0, PATINDEX('%,%',#Value))
-- SELECT #Item
IF(LEN(#Str)>0)
SET #Str = #Str + ', SELECT MAX('+#Item+') as ' +#Item
ELSE
SET#Str = #Str + ' SELECT MAX('+#Item+') as ' +#Item
SET #Value = SUBSTRING(#Value, LEN(#Item + ',') + 1, LEN(#Value))
END
ELSE
BEGIN
SET #Item = #Value
SET #Value = NULL
SET #Str = #Str + 'SELECT MAX('+#Item+') as ' + #Item
END
END
select #Str
See the fiddle sample here
there is a string is "'CNY','THB','USD','VND'" pass from coding.
is there any way that can split it into 'CNY','THB','USD','VND' because I was doing a IN statement. It cannot be done with "'CNY','THB','USD','VND'".
You can use this function, if you are using Microsoft SQL. It will return a table, and in your case you can easily specify if a string in question is in the result set of this table. I am showing you how to use it below
create FUNCTION [dbo].[SPLITSTRING]
(
#CSV varchar(max),
#Delimiter char(1)
)
RETURNS
#Split TABLE (Id int identity(1,1),[OutParam] varchar(max))
AS
BEGIN
Declare #Len as int, #Pos1 int, #Pos2 int
IF LTRIM(RTRIM(#CSV)) = ''
RETURN
SELECT #CSV = #Delimiter + #CSV + #Delimiter
select #Len = len(#csv), #Pos1 = 1
While #Pos1 < #Len
Begin
select #Pos2 = charindex(#Delimiter,#CSV,#Pos1 + 1)
insert #Split select ltrim(rtrim(substring(#csv, #Pos1+1, #Pos2 - #pos1 -1)))
select #Pos1 = #Pos2
End
RETURN
END
Then do
select * from [dbo].[SPLITSTRING]('CNY,THB,USD,VND',',')
What I am doing is creating a table, and splitting out the string between ",", and returning a table.
From above answer , no need of single quote. Pass the string as 'CNY,THB,USD,VND'
in query
Where Varchar_Field IN (select * from [dbo].[SPLITSTRING] ('CNY,THB,USD,VND',','))
Create a Table Vlaued Function
Create FUNCTION [dbo].[Split]
(
#RowData nvarchar(2000),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table
(
Data nvarchar(100)
)
AS
BEGIN
Declare #Cnt int
Set #Cnt = 1
While (Charindex(#SplitOn,#RowData)>0)
Begin
Insert Into #RtnValue (data)
Select
Data = ltrim(rtrim(Substring(#RowData,1,Charindex(#SplitOn,#RowData)-1)))
Set #RowData = Substring(#RowData,Charindex(#SplitOn,#RowData)+1,len(#RowData))
Set #Cnt = #Cnt + 1
End
Insert Into #RtnValue (data)
Select Data = ltrim(rtrim(#RowData))
Return
END
And Create a table where you want to use split string
Declare #SplitString Table
(
SubjectName nvarchar(50)
)
and Call The Function
INSERT INTO #SplitString SELECT * FROM dbo.Split("Your String",'Character from which you want to split')