I'm looking for a select statement in which I can refine values in a nvarchar field.
For example: the input value is '!ab>c2 ghf5 ksj#_+wwl9' and output must be 'abc ghf ksjwwl'. How can I remove some extra characters within a text with SQL regex or other ways?
I don't know if this helps, but you can define a table with all characters / phrases you want to replace and do it like this:
DECLARE #CharsToReplace TABLE(SearchFor VARCHAR(100),ReplaceWith VARCHAR(100));
INSERT INTO #CharsToReplace VALUES('1',''),('2',''),('3',''),('4',''),('5',''),('6',''),('7',''),('8',''),('9',''),('0','');
DECLARE #YourString VARCHAR(100)='abc2 ghf5 ksjwwl9';
SELECT #YourString=REPLACE(#YourString,SearchFor,ReplaceWith)
FROM #CharsToReplace;
SELECT #YourString;
The result
abc ghf ksjwwl
If you'd define values in ReplaceWith this would work too.
UPDATE A function you can use in any select
Attention: This will be slow!
CREATE FUNCTION dbo.DeleteChars(#CharList NVARCHAR(MAX),#string NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #List XML=(SELECT CAST('<x>'+ REPLACE(#CharList,',','</x><x>')+'</x>' AS XML));
SELECT #string=REPLACE(#string,ch.value(N'.',N'nvarchar(max)'),'')
FROM #List.nodes('/x') AS A(ch);
RETURN #string;
END
GO
--Test this with a mock-up table
DECLARE #SomeTable TABLE(SomeColumn VARCHAR(100));
INSERT INTO #SomeTable VALUES('abc2 ghf5 ksjwwl9'),('123 abc 456 hello');
--This is the char list (comma separated)
DECLARE #CharList VARCHAR(100)='1,2,3,4,5,6,7,8,9,0';
--This is how you call it
SELECT dbo.DeleteChars(#CharList,SomeColumn)
FROM #SomeTable
GO
--Clean up
DROP FUNCTION dbo.DeleteChars;
The result
abc ghf ksjwwl
abc hello
Related
How to pass a list of strings as a parameter in a stored procedure in SQL?
Like for example if I have a stored procedure proc_aggregation that takes two parameters #Prod_Desc of varchar data type and another parameter #Prod_Code as a list of strings (Eg : #Prod_Code = ('12012', '12011', '12014')).
You will have to use table valued parameters
Define new type as follows
CREATE TYPE Prod_Code AS TABLE ( ProductCode varchar );
then use this type in your stored procedure
create procedure [dbo].[proc_aggregation]
#Prod_Code Prod_Code READONLY,
#Prod_Desc varchar (30)
as
......
Now before calling the stored procedure fill the table
declare #PC Prod_Code;
insert #PC VALUES ('12012'), ('12011'), ('12014')
Now Call the sp like this
EXEC dbo.proc_aggregation #PC, #Prod_Desc;
You can pass this data as varchar(max) parameter and then parse this string using string_split
Declare #Prod_Code VarChar(max) = '12012,12011,12014'
Select value As [Values]
From String_Split(#Prod_Code, ',')
or pass this data as a json array and parse this text using OPENJSON
Declare #Prod_Code VarChar(max) = '[12012, 12011, 12014]'
Select value As [Values]
From OPENJSON(#Prod_Code)
Values
12012
12011
12014
As an interesting fact, let'us compare performances of the different solutions... STRING, JSON, XML.
SET NOCOUNT ON;
GO
CREATE TABLE #test_list (id int identity primary key, style varchar(16), VAL VARCHAR(64), DT DATETIME2)
GO
-- JSON test
INSERT INTO #test_list VALUES ('JSON', '[12012, 12011, 12014]', SYSDATETIME());
GO
Select value As [Values]
From OPENJSON((SELECT VAL FROM #test_list WHERE style = 'JSON'));
GO 10000
-- STRING test
INSERT INTO #test_list VALUES ('STRING', '12012,12011,12014', SYSDATETIME());
GO
Select value As [Values]
From String_Split((SELECT VAL FROM #test_list WHERE style = 'STRING'), ',')
GO 10000
-- XML test
INSERT INTO #test_list VALUES ('XML', '<i v="12012" /><i v="12011" /><i v="12014" />', SYSDATETIME());
GO
WITH TX AS
(SELECT CAST(VAL AS xml) AS x
FROM #test_list AS i
WHERE style = 'XML')
Select y.value('(#v)[1]', 'varchar(16)')
From TX
CROSS APPLY x.nodes('/i') AS T(y);
GO 10000
-- final
INSERT INTO #test_list VALUES ('END', NULL, SYSDATETIME());
Executing the test without any dataset returned... (SSMS menu : Query/Options/Results/Grid/Ignore results after execution...)
Computing the execution time, is done by this query :
SELECT begins.style,
DATEDIFF(millisecond, begins.DT, ends.DT) AS DurationMS
FROM #test_list AS begins
JOIN #test_list AS ends ON begins.id = ends.id - 1
ORDER BY 2;
It is clear that string solution wins :
style DurationMS
---------------- -----------
STRING 2977
JSON 3358
XML 4242
I want to store values from a SELECT statement into a variable which is capable of holding more than one value because my SELECT statement returns multiple values of type INT. This is how my SP looks like so far.
ALTER PROCEDURE "ESG"."SP_ADD"
AS
BEGIN
DECLARE #Id table(identifiers VARCHAR);
INSERT INTO #Id (identifiers) VALUES('axaa1aaa-aaaa-a5aa-aaaa-aa8aaaa9aaaa');
INSERT INTO #Id (identifiers) VALUES('bxbb1bbb-bbbb-b5bb-bbb4-bb8bbbb9bbbf');
DECLARE #tranID INT = (SELECT
DOCUMENT_SET_.DOCUMENT_SET_TRANSACTION_ID
FROM DOCUMENT_SET_TRANSACTION
WHERE DOCUMENT_SET_TRANSACTION.IDENTIFIER IN (SELECT identifiers FROM #Id));
END
Variable #tranID should be a list or an array to hold the ids. Is it possible to do it SQL Server?
You can declare a variable of type table
DECLARE #tblTrans TABLE (
tranID INT
);
INSERT INTO #tblTrans
SELECT DOCUMENT_SET_TRANSACTION.DOCUMENT_SET_TRANSACTION_ID
FROM ESG.DOCUMENT_SET_TRANSACTION
WHERE DOCUMENT_SET_TRANSACTION.IDENTIFIER
IN (SELECT identifiers FROM #envelopeId);
Depending on what you want to do with the values after this, you could declare a cursor to loop through them or select straight from the variable.
You could also look into using a temporary table depending on what scope you need.
Try this, only take the firs row of example. Do u try this?
select DOCUMENT_SET_TRANSACTION.DOCUMENT_SET_TRANSACTION_ID,
(STUFF((SELECT '-' + convert(varchar(max),DOCUMENT_SET_TRANSACTION.DOCUMENT_SET_TRANSACTION_ID)
FROM ESG.DOCUMENT_SET_TRANSACTION
FOR XML PATH ('')), 1, 2, '')) AS example
FROM ESG.DOCUMENT_SET_TRANSACTION
I want to replace characters , and /. I can do this with:
DECLARE #OMG VARCHAR(200)
SET #OMG = 'ABC,DE/F'
SELECT REPLACE(REPLACE(#OMG,'/','|') ,',','|')
The second query does not work however. Is there just typo or the task cannot be achieved with this code? I wanted to use wildcard for set of characters that should be replaced.
SELECT REPLACE(#OMG,[,/],'|')
It returns:
Msg 207, Level 16, State 1, Line 7
Invalid column name ',/'.
You can define all the variables to be replaced and the replacement inside a table use it.
create TABLE #ReplaceStrings (symb VARCHAR(5),replace_char varchar(5))
INSERT INTO #ReplaceStrings
(symb,replace_char)
VALUES ('/','|'),(',','|')
DECLARE #OMG VARCHAR(200)
SET #OMG = 'ABC,DE/F'
SELECT #OMG = Replace(#OMG, symb, replace_char)
FROM #ReplaceStrings
select #OMG
Here in a single replace you can replace all the unwanted characters.
Update: to replace data from table
create TABLE ReplaceStrings (symb VARCHAR(5),replace_char varchar(5))
create table #table (String varchar(500))
insert into #table values ('ABC,DE/F'),('AB,C,DE/F/')
INSERT INTO ReplaceStrings VALUES ('/','|'),(',','|')
Scalar Function
Create function replacechar(#Ip_String varchar(500))
returns varchar(500)
begin
SELECT #Ip_String=Replace(#Ip_String, symb, replace_char)
FROM ReplaceStrings
return #Ip_String
end
Execute the function
select String,dbo.replacechar(String) Replaced_String from #table
I'm trying to pass a comma separated string such as this: "101:string1,102:string2" into a stored proc and create a temp table out of it. The temp table would have two columns, one integer and one string. It would have two rows for this example. The comma delimits the rows, and the colons delimit the two columns. Anyone know how I can do this? I'm using sql server. Thanks in advance!
EDIT: By the way, I'm not asking about how to create a temp table, only how to create the function.
You can try a Table-Valued Function instead of a temp table. Something like this:
CREATE FUNCTION ListToTable
(
#list nvarchar(4000)
)
RETURNS #return TABLE
(
n int,
s nvarchar(15)
)
AS
BEGIN
SET #list = NULLIF(ltrim(rtrim(#list)),'')
DECLARE #xml AS XML = CAST('<root><row><n>' +
REPLACE(REPLACE(#list,
',', '</s></row><row><n>'),
':', '</n><s>') +
'</s></row></root>' AS XML) ;
INSERT INTO #return (n, s)
SELECT root.row.value('n[1]', 'int')
, root.row.value('s[1]', 'nvarchar(4000)')
FROM #xml.nodes('/root/row') as root(row)
RETURN
END
Usage:
select * from dbo.ListToTable('101:string1,102:string2')
Output:
n s
----------- ---------------
101 string1
102 string2
I need a "replace" select query that strips everything but 3 characters after a string.
Example:
Data = "CN=GOT002086,OU=LAPTOPS,OU=COMPUTERS,OU=GOT,DC=CORP,DC=GDS,DC=COMPANYNAME,DC=COM"
I need to replace the output of this field to only show "GOT". I figured I could key on the word "COMPUTERS" within the column and if possible select only the 3 characters 4 spaces after the word "COMPUTERS". This column is a fully qualified computer name and I only want the OU to be shown.
Try this.
DECLARE #TestString VARCHAR(1000)
SET #TestString = 'CN=GOT002086,OU=LAPTOPS,OU=COMPUTERS,OU=GOT,DC=CORP,DC=GDS,DC=COMPANYNAME,DC=COM'
SELECT SUBSTRING(#TestString, CHARINDEX('COMPUTERS,', #TestString ,0)+13,3)
Updated
CREATE TABLE ActualValuesTable (ValueColumn VARCHAR(250))
INSERT INTO ActualValuesTable VALUES('CN=GOT002086,OU=LAPTOPS,OU=COMPUTERS,OU=GOT,DC=CORP,DC=GDS,DC=COMPANYNAME,DC=COM')
INSERT INTO ActualValuesTable VALUES('CN=GOT002086,OU=LAPTOPS,OU=COMPUTERS,OU=123,DC=CORP,DC=GDS,DC=COMPANYNAME,DC=COM')
INSERT INTO ActualValuesTable VALUES('SomeText..OU=COMPUTERS,OU=789,SomeText..')
INSERT INTO ActualValuesTable VALUES('SomeText..OU=COMPUTERS,OU=012,SomeText..')
INSERT INTO ActualValuesTable VALUES('SomeText..OU=COMPUTERS,OU=234,SomeText..')
INSERT INTO ActualValuesTable VALUES('SomeText..OU=COMPUTERS,OU=456,SomeText..')
SELECT SUBSTRING(ValueColumn, CHARINDEX('COMPUTERS,', ValueColumn ,0)+13,3) FROM ActualValuesTable