SQL Server to Excel using Microsoft Query varchar not showing - sql

I have read a lot of posts that the simplest answer to the issue of special character is to replace your newline characters before running your query. I tried:
REPLACE(REPLACE(Field1, CHAR(10), ' '), CHAR(13), ' ')
I pasted the value into Notepad++ and there is no longer any special characters at least what I can see, I even did a TOP 1 to try only 1 row yet when I run the same query in the Microsoft Query Editor window in Excel the value comes out blank can any shed some light or direct me to another post answer I might have missed.

Not pretty but does the job.
CREATE Function dbo.ufn_RemoveSpecialChars (#str varchar(256)) returns varchar(256)
with schemabinding
begin
if #str is null
return null
declare #str2 varchar(256)
set #str2 = ''
declare #strlen int
set #strlen = len(#str)
declare #p int
set #p = 1
while #p <= #strlen begin
declare #code int
set #code = ascii(substring(#str, #p, 1))
if #code between 32 and 127
set #str2 = #str2 + char(#code)
set #p = #p + 1
end
if len(#str2) = 0
return null
return #str2
end

Related

Using SQL charindex to get string between quotes or multiple strings between occurrence or quotes

we are having to ID some data coming from a bad import and any help would be appreciated.
For instance a string like below and identifier char for the charindex.
SET #InputString = 'The quick brown fox jumped "over" or "under" the log'
SET #IdentifierChar = '"'
The issue we are having is that we can run our test against a hard coded string like the one above and get the result of 'over'. we have tried to put it in a while loop and then we get 'over','or','under'. The Expected Result for us would be only returning 'over', 'under' and not the or.
Our first go at a test was something like below just to see try and split:
DECLARE #InputString Nvarchar(MAX)
DECLARE #IdentifierChar NCHAR(1)
SET #InputString = 'The quick brown fox jumped "over" or "under" the log'
SET #IdentifierChar = '"'
declare #FirstID int
declare #SecondID int
declare #Length int
declare #TargetString Nvarchar(MAX)
Set #FirstID = CHARINDEX(#IdentifierChar,#InputString,1)
Set #SecondID = CHARINDEX(#IdentifierChar,#InputString,#FirstID+1)
Set #Length = #SecondID-#FirstID
Set #TargetString = SUBSTRING(#InputString,#FirstID+1,#Length-1)
Like I said then we literally just threw it in a hard coded loop and set the value of the substring to the last position of the identifier of the specialcharacter just to test and see how the charindex was splitting out the strings between the quotes and we did not think about it getting the 'or' as well.
so here is the dirty loop:
Set #COUNT = 0
Set #Length = 0
WHILE(#COUNT)<3
BEGIN
Set #FirstID = CHARINDEX(#IdentifierChar,#InputString,#Length)
Set #SecondID = CHARINDEX(#IdentifierChar,#InputString,#FirstID+1)
Set #Length = #SecondID-#FirstID
Set #TargetString = SUBSTRING(#InputString,#FirstID+1,#Length-1)
SET #COUNT = #COUNT+1
Set #Length =#SecondID
END
There's probably a better way to parse this out, but here's my minimal modification to your code to make it work, with comments where I changed things:
DECLARE #InputString Nvarchar(MAX)
DECLARE #IdentifierChar NCHAR(1)
SET #InputString = 'The quick brown fox jumped "over" or "under" the log'
SET #IdentifierChar = '"'
declare #FirstID int
declare #SecondID int
declare #Length int
declare #TargetString Nvarchar(MAX)
declare #COUNT int -- added this missing from your code above
Set #COUNT = 0
Set #Length = 0
WHILE(#COUNT)<2 -- only need 2 here now
BEGIN
Set #FirstID = CHARINDEX(#IdentifierChar,#InputString,#Length)
Set #SecondID = CHARINDEX(#IdentifierChar,#InputString,#FirstID+1)
Set #Length = #SecondID-#FirstID
Set #TargetString = SUBSTRING(#InputString,#FirstID+1,#Length-1)
SET #COUNT = #COUNT+1
Set #Length =#SecondID+1 -- added one
print #TargetString -- so we can see what it finds
END
Your main issue was updating #Length at the bottom of your loop -- when you thought you were pointing PAST the double quote after "over", you were actually pointing right at it and finding it a second time as an open-quote before " or ".
Here's a User Defined Function that I wrote and keep in my toolbox. This is a slightly off-label use, but it should work well for you.
If we consider this string to be five substrings, delimited by the four double-quote characters, then we can split on those just take substrings 2 and 4. (Getting a third or fourth quoted value would be as easy as getting substrings 6 or 8) Trying to get an element that doesn't exist will just return a NULL.
After executing the CREATE statement below, which will create the dbo.SPLIT_LIST function, you can call it like this:
declare #InputString varchar(255)
SET #InputString = 'The quick brown fox jumped "over" or "under" the log'
select dbo.SPLIT_LIST(#InputString, '"', 2, ''),
dbo.SPLIT_LIST(#InputString, '"', 4, '')
And you'll get your two output values. What's nice about a function like this is you can just throw it in your select statements and operate over many records at a time, instead of per each.
CREATE function dbo.SPLIT_LIST(
#string nvarchar(max),
#delimiter nvarchar(50),
#i int,
#text_qualifier nvarchar(1)
)
returns nvarchar(max)
/*
returns a selected element from a delimited list
select dbo.SPLIT_LIST_w_Qualifier('"twenty,one","twenty,two","twenty,three"', ',', 2,'"')
returns: 'twenty,two'
Note: can ignore embedded text qualifiers
*/
as
BEGIN
declare #value nvarchar(max),
#d_length int,
#next_delimiter nvarchar(51),
#q_length int, --length of the text qualifier
#trim int,
#using_qualifier int
set #d_length = len(#delimiter)
set #q_length = len(#text_qualifier)
set #string = ltrim(rtrim(#string))
--works by chopping off the leading value from the string each round
while #i > 0 and #string is not null and len(#string) > 0
begin
--if the remaining #string starts with the text qualifier,
--then the currently parsed value should end with the text qualifier+delimiter
if left(#string,1) = #text_qualifier
begin
set #using_qualifier = 1
--chop off leading qualifier
set #string = ltrim(right(#string,(len(#string)-len(#text_qualifier))))
end
else
begin
set #using_qualifier = 0
end
if (#using_qualifier = 0) -- If we are NOT using a text qualifier for this element
begin
if (charindex(#delimiter, #string) > 0) --If there is a remaining delimiter
begin
set #value = ltrim(rtrim(left(#string, charindex(#delimiter, #string)-1)))
set #string = ltrim(rtrim(right(#string, len(#string)-charindex(#delimiter, #string) - #d_length + 1)))
end
else --no remaining delimiters
begin
set #value = #string
set #string = null
end
end
else -- If we ARE using a text qualifier for this element
begin
if (charindex((#text_qualifier+#delimiter), #string) > 0) --If there is a remaining qualifier+delimiter
begin
set #value = ltrim(rtrim(left(#string, charindex((#text_qualifier+#delimiter), #string)-1)))
set #string = ltrim(rtrim(right(#string, len(#string)-charindex((#text_qualifier+#delimiter), #string) - #d_length - #q_length + 1)))
end
else --no remaining qualifier+delimiters
begin
--Does the remaining string END with the text qualifier?
if (charindex(REVERSE(#text_qualifier), REVERSE(#string)) = 1)
begin
set #value = ltrim(rtrim(left(#string, len(#string)-#q_length)))
set #string = null
end
else if (charindex((#text_qualifier), #string) > 0) --Is there a remaining qualifier at all?
begin
set #value = ltrim(rtrim(left(#string, charindex((#text_qualifier), #string)-1)))
set #string = null
end
else --no final closing qualifier
begin
set #value = #string
set #string = null
end
end
end
set #i = #i - 1
--print #value
end
if #i = 0 return #value --should exit here
return NULL --a parse too far exists here
END
Depending on the size of your data set and the complexity of your overall query, you could use a recursive CTE:
;with inputStr as (select 'The quick brown fox jumped "over" or "under" or "around" the log' as s)
,cte as (
select right(s,len(s) - charindex('"',s) + 1) as s --get the first occurence of "
from inputStr
union ALL
select right(right(s,len(s)-1),len(s) - charindex('"',s) + 1) as s --get the second occurence of " in the above string
from cte
where charindex('"',s) > 0 --where " exists
)
select left(s,charindex('"',right(s,len(s)-1))+1) as quoted --select from the first " to the second "
from cte
where (len(s) - len(replace(s,'"',''))) % 2 <> 1 --even number of "
and left(s,charindex('"',right(s,len(s)-1))+1) like '"%"'
Just wanted to update. I continued to toy around with the code and got something to work in case anyone wants to use similar logic in the future. This did what we discussed above.
DECLARE #TargetString NVARCHAR(MAX)
DECLARE #stringLen int
DECLARE #splitTbl TABLE(siteId NVARCHAR(MAX))
DECLARE #idChar NCHAR(1)
SET #TargetString = 'The quick brown fox jumped "over" or "under" the "log"'
SET #stringLen = CHARINDEX(' ', #TargetString)
SET #idChar = '"'
WHILE CHARINDEX(' ', #TargetString) > 0
BEGIN
SET #stringLen = CHARINDEX(' ', #TargetString);
INSERT INTO #splitTbl
SELECT SUBSTRING(#TargetString,1,#stringLen - 1);
SET #TargetString = SUBSTRING(#TargetString, #stringLen + 1,
LEN(#TargetString));
END
DECLARE #buildResults NVARCHAR(MAX)
INSERT INTO #splitTbl
SELECT #TargetString
DECLARE #buildLike NVARCHAR(MAX)
SET #buildLike = '%'+#idChar+'%'
SELECT #buildResults = COALESCE(#buildResults + ', ', '')
+SUBSTRING(siteId, 2, lEN(siteId) - 2)
FROM #splitTbl
WHERE siteId LIKE #buildLike

How to replace this special character at all the places

I tried the following the ways, but result could not be as per requirement( I mean getting same after running replace query). how to replace all the places that special character only?
Here is the Query.
select
REPLACE(description,'‚'COLLATE Latin1_General_BIN, N'‚')
from Zstandars_25Feb2015 where Colname = 56
Result:
.
....the form 𝘹 + 𝘱 = 𝘲 and 𝘱𝘹 = 𝘲 for cases in which 𝘱, 𝘲 and
𝘹 are all nonnegative ..........
whats the type of your description field?
if its varchar, you shouldnt face any problem. I have run your query in my test table and i didnt get such a error, it might be something with your collation, remove collate and try it again or change the collation to something else.
-- Removes special characters from a string value.
-- All characters except 0-9, a-z and A-Z are removed and
-- the remaining characters are returned.
-- Author: Christian d'Heureuse, www.source-code.biz
create function dbo.RemoveSpecialChars (#s varchar(256)) returns varchar(256)
with schemabinding
begin
if #s is null
return null
declare #s2 varchar(256)
set #s2 = ''
declare #l int
set #l = len(#s)
declare #p int
set #p = 1
while #p <= #l begin
declare #c int
set #c = ascii(substring(#s, #p, 1))
if #c between 48 and 57 or #c between 65 and 90 or #c between 97 and 122
set #s2 = #s2 + char(#c)
set #p = #p + 1
end
if len(#s2) = 0
return null
return #s2
end
By keeping N, I am able to fetch the data..
select
REPLACE(description,N'‚'COLLATE Latin1_General_BIN, N'‚')
from Zstandars_25Feb2015 where Colname = 56
Thanks all for the help.

How to toggle case of Entire string in sql

I want to toggle case of entire string.
I am able to do for characters, not for string.
DECLARE #Char AS VARCHAR(1)
SET #Char='a'
IF ASCII(#Char)>=97 AND ASCII(#Char) <=122
PRINT UPPER(#Char)
IF ASCII(#Char)>=65 AND ASCII(#Char) <=90
PRINT LOWER(#Char)
How, I can change case for entire string?
For Ex. "AbCdE", I want to change it to "aBcDe".
You can do it by creating functions:
First make function for one character:
CREATE FUNCTION ToggleChar
(
#Char VARCHAR(1)
)
RETURNS VARCHAR(1)
AS
BEGIN
RETURN CHAR(ASCII(UPPER(#Char))+ASCII(LOWER(#Char))-ASCII(#Char))
END
Then, create function for string:
CREATE FUNCTION ToggleCase
(
#Str VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #ResultStr VARCHAR(MAX)
SET #ResultStr=''
WHILE ( #Str<>'')
BEGIN
SET #ResultStr=#ResultStr + [dbo].[ToggleChar](#Str)
SET #Str= SUBSTRING(#Str,2,LEN(#Str))
END
RETURN #ResultStr
END
Now, use this function to toggle string.
SELECT dbo.ToggleCase('AbCdE') AS ToggleString
Try this:
DECLARE #Name VARCHAR(10) = 'SaMplE'
DECLARE #Count INT = 1
WHILE #Count <= LEN(#Name)
BEGIN
SET #Name = STUFF(#Name, #Count, 1,
CASE
WHEN ASCII(SUBSTRING(#Name,#Count,1)) BETWEEN 97 AND 122 THEN
UPPER(SUBSTRING(#Name,#Count,1))
WHEN ASCII(SUBSTRING(#Name,#Count,1)) BETWEEN 65 AND 90 THEN
LOWER(SUBSTRING(#Name,#Count,1))
END)
SET #Count = #Count + 1
END
SELECT #Name

UDF to insert a text string in to each row of a table

I've been searching high and low for an answer and I can't seem to find anything that points me in the right direction.
I need to create a UDF that will extract each word of a text string and return a table with each word of the string in a separate row.
The UDF is only able to take in one variable '#mytext'.
We can assume that the text string is separated by a single space and may contain commas or periods.
For example, "don’t worry about failures, worry about the chances you miss when you don’t even try." would need to return a table with each word on a separate row of a column without the commas or periods present.
I'm figuring that the text string would need to be separated with a common value that could be used to separate each word for insert, but I could totally be wrong.
Any help with this would be really appreciated!
Based on what I've said so far, here is my far from complete code that I'm not too sure how to proceed with
create function [dbo].[textConverter]
(
#mytext nvarchar(max)
)
returns #text_string table
(
word nvarchar
)
as
begin
set #mytext = replace(#mytext, 'what needs to be changed', 'what it needs to be changed too')
--insert string to table
end
EDIT
I've checked out a couple of links and uncovered a little more information on this, I've now got this code. However it exits with an error. The example that was used in the article I found the code on used numbers in the insert so maybe this is the issue??
create function [dbo].[textConverter]
(
#mytext varchar(max)
)
returns #text_string table
(
word nvarchar
)
as
begin
--Change string to be seperated by commas
set #mytext = replace(#mytext, ' ', ',')
set #mytext = replace(#mytext, '.',',')
--Eliminate double commas
set #mytext = replace(#mytext, ',,', ',')
declare #name nvarchar(255)
declare #pos int
while CHARINDEX(',', #mytext) > 0
begin
select #pos = CHARINDEX(',', #mytext)
select #name = SUBSTRING(#mytext, 1, #pos-1)
insert into #text_string
select #name
select #mytext = SUBSTRING(#mytext, #pos+1, LEN(#mytext)-#pos)
end
insert into #text_string
select #mytext
return
end
--To use function
select * from dbo.textConverter('don’t worry about failures, worry about the chances you miss when you don’t even try.')
See the answer below, It is not in complete shape, but can be developed into a user defined function.
Declare #Sentence Varchar(max) = 'don’t worry about failures, worry about the chances you miss when you don’t even try.'
Set #Sentence = Replace(Replace(Replace(Replace(#Sentence,',',' '),'.',' '),' ',' '),' ',' ')
Declare #e int = (Select Len(#Sentence) - Len(Replace(#Sentence,' ','')))
Declare #s int = 1
Declare #Result Table(id int identity(1,1),Words varchar(max))
--Select #s,#e
While #s <= #e
begin
Insert into #Result
Select Left(#Sentence,Charindex(' ',#Sentence,1)-1)
Set #Sentence = Substring(#Sentence,Charindex(' ',#Sentence,1) + 1,Len(#Sentence) )
Set #s = #s + 1
End
Insert into #Result
Select #Sentence
Select * from #Result
Result
----+-----------
id |Words
----+-----------
1 |don’t
2 |worry
3 |about
4 |failures
5 |worry
6 |about
7 |the
8 |chances
9 |you
10 |miss
11 |when
12 |you
13 |don’t
14 |even
15 |try
----+-----------
I adapted some of the code from http://sqlperformance.com/2012/07/t-sql-queries/split-strings as my situation meant that the delimiter couldn't specified as input. I could only use on input and that was the text string. As such, the following worked for me:
create function [dbo].[textConverter]
(
#string nvarchar(max)
)
returns #output table(splitdata nvarchar(max)
)
begin
--Change string to be seperated by commas
set #string = replace(#string, ' ', ',')
set #string = replace(#string, '.',',')
--Eliminate double commas
set #string = replace(#string, ',,', ',')
declare #start int, #end int
select #start = 1, #end = charindex(',',#string)
while #start < len(#string) + 1
begin
if #end = 0
set #end = len(#string) + 1
insert into #output (splitdata)
values(substring(#string, #start, #end - #start))
set #start = #end + 1
set #end = charindex(',', #string, #start)
end
return
end

How to find 5 digit number in a varchar?

Basically I just need to get a 5 digits number that is separated by a space.
The 5 digits number can be anywhere in the varchar.
Example: I have a varchar column with this various data in SQL 2008 table
travel visa 34322 LLL001
Coffee 34332 Jakarta
FDR001 34312 Taxi cost cash
taxi cash 34321
34556 eating dinner with customer
eating dinner 34256 with customer
visa cost 34221 REF773716637366
the 5 digits number can be anywhere separated by a space
what is best to extract this?
34322
34332
34312
34556
34256
34221
Thanks
Row like this should return blank
Visa refNbr 778738878
Tried the following with no luck yet
SELECT pjtran.tr_comment
,substring(pjtran.tr_comment,PATINDEX('%[0-9]%',pjtran.tr_comment),5)
,Left(SubString(pjtran.tr_comment, PatIndex('%[0-9.-]%', pjtran.tr_comment), 50),PatIndex('%[^0-9.-]%', SubString(pjtran.tr_comment, PatIndex('%[0-9.-]%', pjtran.tr_comment), 50) + 'X')-1)
,len(pjtran.tr_comment)-len(replace(pjtran.tr_comment,' ',''))
I think I need to use a combination of counting the number of space in the varchar. and the above. but I am not sure how to do it
How about something like this?
select substring(tr_comment, patindex('%[0-9][0-9][0-9][0-9][0-9] %', tr_comment), 5) as zip5
If you want to consider that it might be at the end of the string:
select substring(tr_comment, patindex('%[0-9][0-9][0-9][0-9][0-9] %', tr_comment + ' '), 5
) as zip5
use this, this may help you
select SUBSTRING(tr_comment, PATINDEX('%[0-9]%', tr_comment), 5) as zip
Please Try It
CREATE FUNCTION [dbo].[udf_ExtractNumberFromString]
(
#pInputString VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #OutputString varchar(MAX)=''
DECLARE #string varchar(MAX)
DECLARE #start INT
DECLARE #end INT
DECLARE #len INT
SET #string=#pInputString
--SET #string = 'the22478hollies12345TestAddressDr.789324-#345'
SET #string = replace(#string, ' ' , '')
WHILE PATINDEX('%[0-9]%',#string) <> 0
BEGIN
SET #len = len(#string)
-- PRINT #len
set #start = PATINDEX('%[0-9]%',#string)
-- PRINT #start
SET #end= PATINDEX('%[^0-9]%',SUBSTRING(#string,#start,#len-#start))
-- PRINT #end
IF #end=0
BEGIN
SET #end=#len-#start
SET #OutputString=SUBSTRING(#string,#start,#end+1)+'-'+#OutputString
BREAK
END
ELSE
BEGIN
SET #OutputString=SUBSTRING(#string,#start,#end-1)+'-'+#OutputString
SET #string=SUBSTRING(#string,#end+#start-1,#len-#end)
END
--PRINT #string
--PRINT #Output
--PRINT '---------------------'
END
IF LEN(#OutputString)>0
SET #OutputString=LEFT(#OutputString,LEN(#OutputString)-1)
--PRINT #OutputString
RETURN #OutputString
END