select 100000187 from 100000187^Visit-NCH in sql? - sql

How to select 100000187 from 100000187^Visit-NCH in sql?

I use below function for similar functionality.
CREATE FUNCTION [dbo].[fn_Get_Integer_Part]
(
#strAlphaNumeric VARCHAR(256)
)
RETURNS bigint
AS
BEGIN
DECLARE #intAlpha INT;
SET #intAlpha = PATINDEX('%[^0-9]%', #strAlphaNumeric);
BEGIN
WHILE #intAlpha > 0
BEGIN
SET #strAlphaNumeric = STUFF(
#strAlphaNumeric ,
#intAlpha ,
1 ,
'');
SET #intAlpha = PATINDEX('%[^0-9]%', #strAlphaNumeric);
END;
END;
RETURN RIGHT('000000000000' + ISNULL(#strAlphaNumeric, 0), 12)
END;
Usage:
SELECT dbo.fn_Get_Integer_Part('100000187^Visit-NCH');
Result:
100000187

Given your comment in OP,
I want everything before '^'
The following query is what you seek:
SELECT LEFT(<column>, CHARINDEX('^',<column>)-1) AS 'Stripped Column' FROM <table>

CREATE FUNCTION [dbo].[REMOVE_NONINTEGERS](#TEXT VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #Reset BIT;
DECLARE #Ret VARCHAR(8000);
DECLARE #i INT;
DECLARE #c CHAR(1);
DECLARE #CharLength INT
DECLARE #CHARSTART INT
DECLARE #RESULT VARCHAR(MAX)
SET #I = 1
SET #CHARSTART = 0
WHILE (#i <= LEN(#Text))
BEGIN
SET #CHARSTART = #CHARSTART + 1
SET #RET = SUBSTRING(#TEXT,#CHARSTART,1)
IF(#RET NOT in('0','1','2','3','4','5','6','7','8','9'))
BEGIN
SET #RET = ISNULL(#RET,'')
SET #I = #I + 1
END
ELSE
BEGIN
SET #RESULT = ISNULL(#RESULT,'') + #RET
SET #I = #I + 1
END
END
RETURN #RESULT
END
SELECT [dbo].[REMOVE_NONINTEGERS]('100000187^Visit-NCH')

Related

MSG 537 :Invalid length parameter passed to the LEFT or SUBSTRING function

when i create a function in sql server 2012 , in this function
CREATE FUNCTION howords (#str nvarchar(50), #word nvarchar(50))
RETURNS int
AS
BEGIN
DECLARE #tempstr nvarchar(max)
DECLARE #space int
DECLARE #count int
DECLARE #size int
SET #count = 0
WHILE (LEN(#str) >= 0)
BEGIN
SET #space = CHARINDEX(' ', #str, 1)
SET #tempstr = LEFT(#str, (#space - 1))
IF (#tempstr = #word)
SET #count = #count + 1
SET #size = LEN(#tempstr)
IF (((LEN(#str)) - #space) > 0)
SET #str = SUBSTRING(#str, #space + 1, ((LEN(#str)) - #space))
IF (((LEN(#str)) - #space) <= 0)
BEGIN
IF (#str = #word)
SET #count = 0
WHILE (LEN(#str) > 0)
BEGIN
SET #space = CHARINDEX(' ', #str + 1)
SET #tempstr = LEFT(#str, (#space - 1))
IF (#tempstr = #word)
SET #count = #count + 1
SET #size = LEN(#tempstr)
IF (((LEN(#str)) - #space) > 0)
SET #str = SUBSTRING(#str, #space + 1, ((LEN(#str)) - #space))
IF (((LEN(#str)) - #space) <= 0)
BEGIN
IF (#str = #word)
SET #count = #count + 1
BREAK
END
END
END
END
RETURN #count
END
when i exec this query
select dbo.howords ('hello my hello','hello' )
i want to give me count (2)
but it give me an error
MSG 537 :Invalid length parameter passed to the LEFT or SUBSTRING function.
any help?
Try this
DECLARE #tosearch VARCHAR(MAX)='Hello'
DECLARE #string VARCHAR(MAX)='hello my hello'
SELECT (DATALENGTH(#string)-DATALENGTH(REPLACE(#string,#tosearch,'')))/DATALENGTH(#tosearch)
AS OccurrenceCount

SQL - Replace non numeric characters in string

I'm writing a function that takes a string and has to replace any non-numeric character with two numeric characters taken from a table. This is the code I use to explore the string and find the non-numeric characters:
SET #string = '1a2b3c4d'
SET #wcount= 0
SET #index = 1
SET #len= LEN(#string)
WHILE #index<= #len
BEGIN
SET #char = SUBSTRING(#string, #index, 1)
IF #char LIKE '%[a-z]%'
PRINT 'char ' + CONVERT(varchar(10), #index)
ELSE
PRINT #char
SET #index= #index+ 1
END
The output is the following
1
char 2
2
char 4
3
char 6
4
char 8
Now, when I find a non-numeric character I have to replace it with two numeric chars taken from a table by a select. E.g.
SELECT #temp = REPLACEMENT FROM Conversion_Tab WHERE EXPR = #char
In conclusion, if I have the following string '1a2a3a4a' and the replacement for 'a' is '88' the resulting string should be '188288388488'
Thanks in advance for any help.
Bye!
Try this
DECLARE #string VARCHAR(100)
DECLARE #outstring VARCHAR(100)
DECLARE #wcount INT
DECLARE #temp INT
DECLARE #index INT
DECLARE #len INT
DECLARE #char CHAR
SET #string = '1a2a3a4a'
SET #wcount= 0
SET #index = 1
SET #len= LEN(#string)
SET #outstring = ''
WHILE #index<= #len
BEGIN
SET #char = SUBSTRING(#string, #index, 1)
IF #char LIKE '%[a-z]%'
BEGIN
SELECT #temp = REPLACEMENT FROM #Conversion_Tab WHERE EXPR = #char
SET #outstring = #outstring + CONVERT(VARCHAR(10),#temp)
END
ELSE
BEGIN
SET #outstring = #outstring + #char
END
SET #index= #index+ 1
END
SELECT #outstring
SQL FIDDLE DEMO
looks like you need isnumeric(). so if not isnumeric(char) replace it with your lookup value.
taken from the other answer but produces the same result
DECLARE #string VARCHAR(100)
DECLARE #outstring VARCHAR(100)
DECLARE #wcount INT
DECLARE #temp INT
DECLARE #index INT
DECLARE #len INT
DECLARE #char CHAR
SET #string = '1a2a3a4a'
SET #wcount= 0
SET #index = 1
SET #len= LEN(#string)
SET #outstring = ''
WHILE #index<= #len
BEGIN
SET #char = SUBSTRING(#string, #index, 1)
IF ISNUMERIC(#char) = 0
BEGIN
SELECT #temp = REPLACEMENT FROM #Conversion_Tab WHERE EXPR = #char
SET #outstring = #outstring + CONVERT(VARCHAR(10),#temp)
END
ELSE
BEGIN
SET #outstring = #outstring + #char
END
SET #index= #index+ 1
END

Converting String List into Int List in SQL

I have a nvarchar(MAX) in my stored procedure which contains the list of int values, I did it like this as it is not possible to pass int list to my stored procedure,
but, now I am getting problem as my datatype is int and I want to compare the list of string.
Is there a way around by which I can do the same?
---myquerry----where status in (#statuslist)
but the statuslist contains now string values not int, so how to convert them into INT?
UPDate:
USE [Database]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP]
(
#FromDate datetime = 0,
#ToDate datetime = 0,
#ID int=0,
#List nvarchar(MAX) //This is the List which has string ids//
)
AS
SET FMTONLY OFF;
DECLARE #sql nvarchar(MAX),
#paramlist nvarchar(MAX)
SET #sql = 'SELECT ------ and Code in(#xList)
and -------------'
SELECT #paramlist = '#xFromDate datetime,#xToDate datetime,#xId int,#xList nvarchar(MAX)'
EXEC sp_executesql #sql, #paramlist,
#xFromDate = #FromDate ,#xToDate=#ToDate,#xId=#ID,#xList=#List
PRINT #sql
So when I implement that function that splits then I am not able to specify the charcter or delimiter as it is not accepting it as (#List,',').
or (','+#List+',').
It is possible to send an int list to your stored procedure using XML parameters. This way you don't have to tackle this problem anymore and it is a better and more clean solution.
have a look at this question:
Passing an array of parameters to a stored procedure
or check this code project:
http://www.codeproject.com/Articles/20847/Passing-Arrays-in-SQL-Parameters-using-XML-Data-Ty
However if you insist on doing it your way you could use this function:
CREATE FUNCTION [dbo].[fnStringList2Table]
(
#List varchar(MAX)
)
RETURNS
#ParsedList table
(
item int
)
AS
BEGIN
DECLARE #item varchar(800), #Pos int
SET #List = LTRIM(RTRIM(#List))+ ','
SET #Pos = CHARINDEX(',', #List, 1)
WHILE #Pos > 0
BEGIN
SET #item = LTRIM(RTRIM(LEFT(#List, #Pos - 1)))
IF #item <> ''
BEGIN
INSERT INTO #ParsedList (item)
VALUES (CAST(#item AS int))
END
SET #List = RIGHT(#List, LEN(#List) - #Pos)
SET #Pos = CHARINDEX(',', #List, 1)
END
RETURN
END
Call it like this:
SELECT *
FROM Table
WHERE status IN (SELECT * from fnStringList2Table(#statuslist))
You can work with string list too. I always do.
declare #statuslist nvarchar(max)
set #statuslist = '1, 2, 3, 4'
declare #sql nvarchar(max)
set #sql = 'select * from table where Status in (' + #statuslist + ')'
Execute(#sql)
You can do this by using sql function which will return you an integer array..
It would be great if you pass #Delimiter separated string to your stored procedure which could be processed properly afterwards.
Write one function to split the data as following
CREATE FUNCTION [dbo].[SplitValues] (#StringArray NVARCHAR(MAX), #Delimiter NVARCHAR(10))
RETURNS #ResultedValues table
(
ResultValue INT
)
AS
BEGIN
DECLARE #Tokens TABLE(Token nvarchar)
DECLARE #String nvarchar
WHILE (CHARINDEX(#Delimiter,#StringArray)>0)
BEGIN
INSERT INTO #Tokens (Token) VALUES (LTRIM(RTRIM(SUBSTRING(#StringArray,1,CHARINDEX(#Delimiter,#StringArray)-1))))
SET #String = SUBSTRING(#StringArray,
CHARINDEX(#Delimiter,#StringArray)+LEN(#Delimiter),LEN(#StringArray))
END
INSERT INTO #ResultedValues (ResultValue ) VALUES ( CAST(LTRIM(RTRIM(#String)) AS INT))
RETURN
END
And then use it like following, i am using (,) as #Delimiter here
SELECT ResultValue [YourSchema].[SplitValues](#statuslist,',')
Actually, you can send the list of int values to your procedure by creating a User Defined Table Type. However, this implies more work in order to populate the table parameter.
In your case, you can use the sp_executesql stored procedure to achieve what you want like this:
declare #statement nvarchar(4000) = '----your query---- where status in ('
+ #statusList +')'
sp_executesql #statement
here is an example of how to do it and the Link for more informations
ALTER FUNCTION iter_intlist_to_tbl (#list nvarchar(MAX))
RETURNS #tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL,
number int NOT NULL) AS
BEGIN
DECLARE #startpos int,
#endpos int,
#textpos int,
#chunklen smallint,
#str nvarchar(4000),
#tmpstr nvarchar(4000),
#leftover nvarchar(4000)
SET #textpos = 1
SET #leftover = ''
WHILE #textpos <= datalength(#list) / 2
BEGIN
SET #chunklen = 4000 - datalength(#leftover) / 2
SET #tmpstr = ltrim(#leftover + substring(#list, #textpos, #chunklen))
SET #textpos = #textpos + #chunklen
SET #startpos = 0
SET #endpos = charindex(' ' COLLATE Slovenian_BIN2, #tmpstr)
WHILE #endpos > 0
BEGIN
SET #str = substring(#tmpstr, #startpos + 1, #endpos - #startpos - 1)
IF #str <> ''
INSERT #tbl (number) VALUES(convert(int, #str))
SET #startpos = #endpos
SET #endpos = charindex(' ' COLLATE Slovenian_BIN2, #tmpstr, #startpos + 1)
END
SET #leftover = right(#tmpstr, datalength(#tmpstr) / 2 - #startpos)
END
IF ltrim(rtrim(#leftover)) <> ''
INSERT #tbl (number) VALUES(convert(int, #leftover))
RETURN
END
-- ############################ Example ############################
--CREATE PROCEDURE get_product_names_iter #ids varchar(50) AS
--SELECT P.ProductName, P.ProductID
--FROM Northwind..Products P
--JOIN iter_intlist_to_tbl(#ids) i ON P.ProductID = i.number
--go
--EXEC get_product_names_iter '9 12 27 37'
-- ############################ WICHTIG ############################
This works for me on an Informix DataBase:
DROP FUNCTION rrhh:fnc_StringList_To_Table;
CREATE FUNCTION rrhh:fnc_StringList_To_Table (pStringList varchar(250))
RETURNING INT as NUMERO;
/* A esta Funcion le podes pasar una cadena CSV con una lista de numeros
* Ejem: EXECUTE FUNCTION fnc_StringList_To_Table('1,2,3,4');
* y te devolvera una Tabla con dichos numeros separados uno x fila
* Autor: Jhollman Chacon #Cutcsa - 2019 */
DEFINE _STRING VARCHAR(255);
DEFINE _LEN INT;
DEFINE _POS INT;
DEFINE _START INT;
DEFINE _CHAR VARCHAR(1);
DEFINE _VAL INT;
LET _STRING = REPLACE(pStringList, ' ', '');
LET _START = 0;
LET _POS = 0;
LET _LEN = LENGTH(_STRING);
FOR _POS = _START TO _LEN
LET _CHAR = SUBSTRING(pStringList FROM _POS FOR 1);
IF _CHAR <> ',' THEN
LET _VAL = _CHAR::INT;
ELSE
LET _VAL = NULL;
END IF;
IF _VAL IS NOT NULL THEN
RETURN _VAL WITH RESUME;
END IF;
END FOR;
END FUNCTION;
EXECUTE FUNCTION fnc_StringList_To_Table('1,2,3,4');
SELECT * FROM TABLE (fnc_StringList_To_Table('1,2,3,4'));

SQL code for anagram

I have a SQL code for finding whether two words are anagram or not.
DECLARE #str1 VARCHAR(100), #str2 VARCHAR(100)
SELECT #str1 = 'mmaa', #str2 = 'mama'
IF LEN(#str1) <> LEN(#str2)
BEGIN
SELECT 'NOT EQUAL'
END
ELSE
BEGIN
IF (SELECT COUNT(*) FROM
(
select substring(#str1, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str1) AND number > 0
UNION
select substring(#str2, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str2) AND number > 0
)
t)
= LEN(#str1)
SELECT '1 anagram'
ELSE
SELECT '0 not anagram'
END
But for words like mmaa and mama this program returns not anagram. But they are anagrams. How can I solve this problem?
rather crude, but how about:
Declare #S1 varChar(100) = 'mmaa'
Declare #S2 varChar(100) = 'mama'
Declare #c char(1)
Declare #i tinyint
Declare #o1 varChar(100) = ''
Declare #o2 varChar(100) = ''
While DataLength(#s1) > 0 Begin
Set #c = Left(#s1, 1)
Set #s1 = Substring(#s1, 2, len(#s1))
Set #i = 1
While #i <= Len(#o1) And #c > substring(#o1, #i, 1) Set #i += 1
Set #o1 = left(#o1, #i-1) + #c + substring(#o1, #i, len(#o1))
End
While DataLength(#s2) > 0 Begin
Set #c = Left(#s2, 1)
Set #s2 = Substring(#s2, 2, len(#s2))
Set #i = 1
While #i <= Len(#o2) And #c > substring(#o2, #i, 1) Set #i += 1
Set #o2 = left(#o2, #i-1) + #c + substring(#o2, #i, len(#o2))
End
Select case When #o1 = #o2 Then 'Anagram' Else 'Not Anagram' End
or to encapsulate the sort into a function,
Create FUNCTION [dbo].[SortString](#s varChar(8000))
RETURNS varChar(8000)
As
Begin
Declare #c char(1)
Declare #i int
Declare #out varChar(8000) = left(#s, 1)
While DataLength(#s) > 0 Begin
Set #s = Substring(#s, 2, len(#s)-1)
Set #c = Left(#s, 1)
Set #i = 0
While #i < Len(#out) And #c > substring(#out, #i+1, 1) Set #i += 1
Set #out = case when #i < Len(#out)
then stuff(#out, #i+1, 0, #c)
else #out + #c end
End
return #out
End
Please try using CHECKSUM_AGG
DECLARE #str1 VARCHAR(100), #str2 VARCHAR(100)
SELECT #str1 = 'mmaa', #str2 = 'mama'
IF LEN(#str1) <> LEN(#str2)
BEGIN
SELECT 'NOT EQUAL'
END
ELSE
BEGIN
IF(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM (select substring(#str1, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str1) AND number > 0)T1)=
(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM (select substring(#str2, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str2) AND number > 0)T2)
SELECT '1 anagram'
ELSE
SELECT '0 not anagram'
END

Strange error in this SQL Server stored procedure

I found the following stored procedure from here, while creating this stored procedure in my database, I get this error message: (I'm running SQL Server 2008 Developer)
Msg 102, Level 15, State 1, Procedure HighLightSearch, Line 23
Incorrect syntax near '+'.
Here is the full Stored Procedure code:
CREATE FUNCTION [dbo].[HighLightSearch](#contents NVARCHAR(MAX), #searchTerm NVARCHAR(4000), #style NVARCHAR(4000), #maxLen INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #c NCHAR(1)
DECLARE #len INT = 0
DECLARE #l INT = 0
DECLARE #p INT = 0
DECLARE #prevPos INT = 0
DECLARE #margin INT
DECLARE #term NVARCHAR(4000)
DECLARE #retval NVARCHAR(MAX) = ''
DECLARE #positions TABLE
(
S INT,
L INT
)
-- find all occurances of the search term
DECLARE cur1 CURSOR FOR
SELECT display_term FROM sys.dm_fts_parser(N'FORMSOF(FREETEXT, "' + #searchTerm + '")', 1033, 0, 1)
OPEN cur1
FETCH NEXT FROM cur1 INTO #term
WHILE ##FETCH_STATUS = 0
BEGIN
WHILE 1 = 1
BEGIN
SET #p = CHARINDEX(#term, #contents, #p)
IF #p <= 0 BREAK
SET #l = LEN(#term)
IF #p > 0 BEGIN
SET #c = SUBSTRING(#contents, #p - 1, 1)
IF #c <> ' ' AND #c <> NCHAR(9) AND #c <> NCHAR(13) AND #c <> NCHAR(10) BREAK
END
INSERT INTO #positions (S, L) VALUES(#p, #l)
SET #p = #p + LEN(#term)
END
FETCH NEXT FROM cur1 INTO #term
END
CLOSE cur1
DEALLOCATE cur1
-- build the result string
DECLARE cur2 CURSOR FOR
SELECT S, MAX(L)
FROM #positions
GROUP BY S
ORDER BY S
SET #margin = LOG(#maxLen) * 5
IF #margin > #maxLen / 4 SET #margin = #maxLen / 4
SELECT #prevPos = MIN(S) - #margin FROM #positions
OPEN cur2
FETCH NEXT FROM cur2 INTO #p, #l
WHILE ##FETCH_STATUS = 0 AND #len < #maxLen
BEGIN
SET #retval = #retval + SUBSTRING(#contents, #prevPos, #p - #prevPos)
SET #retval = #retval + '<span style="' + #style + '">' + SUBSTRING(#contents, #p, #l) + '</span>'
SET #len = #len + #p - #prevPos + #l
SET #prevPos = #p + #l
FETCH NEXT FROM cur2 INTO #p, #l
END
CLOSE cur2
DEALLOCATE cur2
SET #margin = LOG(#maxLen) * 5
IF #margin + #len < #maxLen SET #margin = #maxLen - #len
IF #margin > 0 SET #retval = #retval + SUBSTRING(#contents, #prevPos, #l)
RETURN '...' + #retval + '...'
END
Try doing
DECLARE #var NVARCHAR(4000)
SET #var=N'FORMSOF(FREETEXT, "' + #searchTerm + '")'
DECLARE cur1 CURSOR FOR
SELECT display_term FROM sys.dm_fts_parser(#var, 1033, 0, 1)