I am using a function that I found here and else where on the internet to try and strip illegal characters from a field.
Create Function [epacube].[StripSpecs](#myString varchar(500),
#invalidChars varchar(100)) RETURNS varchar(500) AS Begin
While PatIndex(#invalidChars, #myString) > 0
Set #myString = Stuff(#myString, PatIndex(#invalidChars, #myString), 1, '')
Return #myString End
in my table I have set my field value to be: set DATA_NAME = 'Pro$d)uc^t'
If I run this query:
SELECT epacube.StripSpecs (
DATA_NAME
,'%$%') FROM TABLE_DATA
It works and I get a value returned of Prod)uc^t
However, if I add another special character, it no longer works:
SELECT epacube.StripSpecs (
DATA_NAME
,'%$)%') FROM TABLE_DATA
returns my original value Pro$d)uc^t
Does anyone have any suggestion for accomplishing what I need to do?
EDIT
As per the answer below here is the code that worked:
Create Function [epacube].[StripSpecs](#myString varchar(500), #invalidChars varchar(100))
RETURNS varchar(500) AS
Begin
While PatIndex('%[' + #invalidChars + ']%', #myString) > 0
Set #myString = Stuff(#myString, PatIndex('%[' + #invalidChars + ']%', #myString), 1, '')
Return #myString
End
As with LIKE, if you want to specify that one of a set of characters should match, use [] to enclose the set.
SELECT epacube.StripSpecs (
DATA_NAME
,'%[$)]%') FROM TABLE_DATA
Although, personally, given the descriptions of the function and parameters, I'd add the %[ and ]% in StripSpecs, and let the caller just give a list of characters (if you don't want to support any other type of pattern being specified)
Related
I did following store procedure using dynamic query, see the following blueprint of code
ALTER PROCEDURE [dbo].[usp_Report] (
#LocationId INT = NULL
,#UserId INT = NULL)
DECLARE #miscquery NVARCHAR (MAX);
begin
SET #miscquery='
SELECT
,A.AgreementNumber AS Contract
,A.AgreementId
FROM tblAgreement A
WHERE
AND (A.IsDeleted = 0 or A.IsDeleted is null)
AND (
(
' + convert(NVARCHAR(30), #LocationId) + ' IS NULL
AND (
A.CheckoutLocation IN (
SELECT LocationId
FROM [dbo].[tblUserLocations]
WHERE UserID = ' + convert(VARCHAR(10), #userId) +'
AND IsDeleted = 0
)
OR A.CheckoutLocation IS NULL
)
)
OR A.CheckoutLocation = ' + convert(VARCHAR(10), #LocationId) +'
)'
EXEC (#miscquery)
end
)
here when i execute the query with #Locationid is null, results doesn't return table, it returns like following
(63 rows affected)
(2325 rows affected)
please help me. thank you
The code you have there cannot be your actual code, firstly because right at the start you try to set a variable called #miscquery before you declare it. There's also no reason for this code to be dynamic, so it's clear you're doing some other stuff as well.
I will take it as a given that for some reason you "need" dynamic SQL. I will put in the standard warning about sanitising your inputs. That was it.
OK. Even if #miscquery had been declared, the code as written will not produce any results. It will either throw a syntax error, or do nothing, depending on your setting for concat_null_yields_null.
Let's take the likely case: you have the default setting for this, which means that when you concatenate a varchar to null, the result is null.
Observe the following code:
declare #locationId int = null;
select 'this sentence ends with...' + convert(nvarchar(30), #locationId);
What will be the output?
"This sentence ends with... null"
"This sentence ends with..."
null
The answer is 3. And notice: that's not a string with the value "null". That's just null. When you convert the null value to a string, you don't get a string with the value "null", you get the null value.
OK, so now we try to add null to the end of our string. When you try to concatenate the null value to a string with the + operator, the entire result is null.
Therefore, your entire #miscquery variable is null at the end of the assignment.
So what you are then doing is the same as this:
declare #myquery varchar(max) = null;
exec sp_executesql #myquery
Which is valid, and doesn't throw any error, but does nothing. Then the rest of your code does whatever it does, and produces the results you see.
if concat_null_yields_null was set to off then you would get a syntax error, because the resulting text would not be valid SQL when you handed it to sp_executesql.
As Dan said, the best and safest solution would be to parameterize your inputs. But putting that aside, the solution you need would look something like the following. In the iif() function, I look at the value of #locationId. If it is null, then I want the string "null". If it is not null, then I want the string conversion of whatever value it has.
declare #locationId int = null;
declare #query varchar(max) =
'select * from mytable where '
+ iif(#locationId is null, 'null', convert(nvarchar(30), #locationId))
+ ' is null';
print #query;
I need to create a T-SQL function that only keeps a hyphen (dash '-') and removes all non-alphanumeric characters (plus all spaces, superscripts and subscripts) from a given string.
You can test Superscript/Subscripts in SSMS:
select 'Hello® World™ '
Example:
input string
output string:
HelloWorld-ThisIsATest123
Any solutions or thoughts will be appreciated.
Check this link. This removes all alpha numeric characters. You can include '-' also to the included list.
How to strip all non-alphabetic characters from string in SQL Server?
In this example for the answer from #George Mastros, use '%[^a-zA-Z0-9-]%' for regular expression instead of '%[^a-z]%'
Here is the reformatted function to include '-' and numeric characters:
-- Reformatted function
Create Function [dbo].[RemoveNonAlphaCharacters](#Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare #KeepValues as varchar(50)
Set #KeepValues = '%[^a-zA-Z0-9\-]%'
While PatIndex(#KeepValues, #Temp) > 0
Set #Temp = Stuff(#Temp, PatIndex(#KeepValues, #Temp), 1, '')
Return #Temp
End
--Call function
Select dbo.RemoveNonAlphaCharacters('Hello® World™ -123 !##$%^')
OUTPUT: HelloWorld-123
I identified my code's issue - I previously had exact same function which was NOT removing superscript / subscript, and I was wondering why. Here was the issue: The input/output datatype should NOT be NVARCHAR , but mere varchar, else it will contain superscripts in the return string:
problem code :
Create Function [dbo].[RemoveNonAlphaCharacters](#Temp NVarChar(1000))
Returns NVarChar(1000)
AS
...
I've created a full-text indexed column on a table.
I have a stored procedure to which I may pass the value of a variable "search this text". I want to search for "search", "this" and "text" within the full-text column. The number of words to search would be variable.
I could use something like
WHERE column LIKE '%search%' OR column LIST '%this%' OR column LIKE '%text%'
But that would require me to use dynamic SQL, which I'm trying to avoid.
How can I use my full-text search to find each of the words, presumably using CONTAINS, and without converting the whole stored procedure to dynamic SQL?
If you say you definitely have SQL Table Full Text Search Enabled, Then you can use query like below.
select * from table where contains(columnname,'"text1" or "text2" or "text3"' )
See link below for details
Full-Text Indexing Workbench
So I think I came up with a solution. I created the following scalar function:
CREATE FUNCTION [dbo].[fn_Util_CONTAINS_SearchString]
(
#searchString NVARCHAR(MAX),
#delimiter NVARCHAR(1) = ' ',
#ANDOR NVARCHAR(3) = 'AND'
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
IF #searchString IS NULL OR LTRIM(RTRIM(#searchString)) = '' RETURN NULL
-- trim leading/trailing spaces
SET #searchString = LTRIM(RTRIM(#searchString))
-- remove double spaces (prevents empty search terms)
WHILE CHARINDEX(' ', #searchString) > 0
BEGIN
SET #searchString = REPLACE(#searchString,' ',' ')
END
-- reformat
SET #searchString = REPLACE(#searchString,' ','" ' + #ANDOR + ' "') -- replace spaces with " AND " (quote) AND (quote)
SET #searchString = ' "' + #searchString + '" ' -- surround string with quotes
RETURN #searchString
END
I can get my results:
DECLARE #ftName NVARCHAR (1024) = dbo.fn_Util_CONTAINS_SearchString('value1 value2',default,default)
SELECT * FROM Table WHERE CONTAINS(name,#ftName)
I would appreciate any comments/suggestions.
For your consideration.
I understand your Senior wants to avoid dynamic SQL, but it is my firm belief that Dynamic SQL is NOT evil.
In the example below, you can see that with a few parameters (or even defaults), and a 3 lines of code, you can:
1) Dynamically search any source
2) Return desired or all elements
3) Rank the Hit rate
The SQL
Declare #SearchFor varchar(max) ='Daily,Production,default' -- any comma delim string
Declare #SearchFrom varchar(150) ='OD' -- table or even a join statment
Declare #SearchExpr varchar(150) ='[OD-Title]+[OD-Class]' -- Any field or even expression
Declare #ReturnCols varchar(150) ='[OD-Nr],[OD-Title]' -- Any field(s) even with alias
Set #SearchFor = 'Sign(CharIndex('''+Replace(Replace(Replace(#SearchFor,' , ',','),', ',''),',',''','+#SearchExpr+'))+Sign(CharIndex(''')+''','+#SearchExpr+'))'
Declare #SQL varchar(Max) = 'Select * from (Select Distinct'+#ReturnCols+',Hits='+#SearchFor+' From '+#SearchFrom + ') A Where Hits>0 Order by Hits Desc'
Exec(#SQL)
Returns
OD-Nr OD-Title Hits
3 Daily Production Summary 2
6 Default Settings 1
I should add that my search string is comma delimited, but you can change to space.
Another note CharIndex can be substanitally faster that LIKE. Take a peek at
http://cc.davelozinski.com/sql/like-vs-substring-vs-leftright-vs-charindex
I need to remove all brackets and their contents from multiple records but I can't figure out the best way to do this.
I would like to be able to write something like
SELECT dbo.RemoveBracketedText(ColumnName) FROM TableName;
And it would convert a record such as 'Hello (World)' to just 'Hello '
Any help is appreciated.
Thanks!
My first approach would probably have been to write a quick c# app to do it or use SSIS and write a package to take care of it, but if your determined to use tsql... it will likely require a combination of a recursive function and some string manipulation.
This is minimally tested but should be close. (i.e. it worked on the sample text you provide in your question).
CREATE FUNCTION RemoveBracketedText (#sourceString varchar(max))
RETURNS varchar(max)
AS
BEGIN
DECLARE #pStart Int
DECLARE #pEnd Int
DECLARE #pTarget varchar(max)
DECLARE #pResult varchar(max)
SET #pStart = CHARINDEX('(', #sourceString)
SET #pEnd = CHARINDEX(')', #sourceString, #pStart) /** start looking from pos of opening bracket */
IF #pEnd > #pStart AND #pEnd > 0 /** basic error avoidance */
BEGIN
SET #pTarget = SUBSTRING(#sourceString, #pStart, #pEnd - #pStart + 1)
SET #pResult = Replace(#sourceString, #pTarget, '')
/** recursion to get rid of more than one set of brackets per string */
IF CHARINDEX('(', #pResult) > 0 AND CHARINDEX(')', #pResult) > CHARINDEX('(', #pResult)
BEGIN
SET #pResult = dbo.RemoveBracketedText(#pResult)
END
END
ELSE
BEGIN
SET #pResult = #sourceString /** no matching set of brackets found */
END
RETURN #pResult
END
select ltrim(rtrim(
replace(
replace(ColumnName,
substring(ColumnName,
charindex('(',ColumnName),
charindex(')',ColumnName) - charindex('(',ColumnName) + 1),
''),
' ',' ')
)) from TableName;
This is in SQL Server 2005. I have a varchar column and some rows contain trailing space, e.g. abc, def.
I tried removing the trailing space with this command:
update thetable
set thecolumn = rtrim(thecolumn)
But the trailing space remains. I tried to find them using:
select *
from thetable
where thecolumn <> rtrim(thecolumn)
But it returned nothing.
Are there some settings that I am not aware that influences trailing space check?
EDIT:
I know that there is trailing space from SSMS, when I copy paste the value from the grid to the editor, it has trailing space.
Check if the spaces that are not removed have the ASCII code 32.
Try this to replace "hard space" with "soft space":
update thetable set thecolumn = rtrim(replace(thecolumn, char(160), char(32)))
the query was missing equal sign
Are you certain that it is a space (ascii 32) character? You can get odd behavior with other "non-visible" characters. Try running
select ascII(right(theColumn, 1))
from theTable
and see what you get.
Use this Function:
Create Function [dbo].[FullTrim] (#strText varchar(max))
Returns varchar(max) as
Begin
Declare #Ch1 char,#ch2 char
Declare #i int,#LenStr int
Declare #Result varchar(max)
Set #i=1
Set #LenStr=len(#StrText)
Set #Result=''
While #i<=#LenStr
Begin
Set #ch1=SUBSTRING(#StrText,#i,1)
Set #ch2=SUBSTRING(#StrText,#i+1,1)
if ((#ch1=' ' and #ch2=' ') or (len(#Result)=0 and #ch1=' '))
Set #i+=1
Else
Begin
Set #Result+=#Ch1
Set #i+=1
End
End
Return #Result
End
In SQL, CHAR(n) columns are right-padded with spaces to their length.
Also string comparison operators (and most functions too) do not take the trailing spaces into account.
DECLARE #t TABLE (c CHAR(10), vc VARCHAR(10))
INSERT
INTO #t
VALUES ('a ', 'a ')
SELECT LEN(c), LEN(vc), с + vc
FROM #t
--
1 1 "a a"
Please run this query:
SELECT *
FROM thetable
WHERE thecolumn + '|' <> RTRIM(thecolumn) + '|'
and see if it finds something.
It sounds like either:
1) Whatever you are using to view the values is inserting the trailing space (or the appearance thereof- try a fixed-width font like Consolas).
2) The column is CHAR, not VARCHAR. In that case, the column will be padded with spaces up to the length of the column, e.g. inserting 'abc' into char(4) will always result in 'abc '
3) You are somehow not committing the updates, not updating the right column, or other form of user error. The update statement itself looks correct on the face of it.
I had the same issues with RTRIM() AND LTRIM() functions.
In my situation the problem was in LF and CR chars.
Solution
DECLARE #test NVARCHAR(100)
SET #test = 'Declaration status '
SET #test = REPLACE(REPLACE(#test, CHAR(10), ''), CHAR(13), '')