Like used with parameter don't work correctly - tsql

This script should only pick the rows with brickurl = 'http://www.bol.com/something'
But it returns nearly all 30 rows, even with totally other texts in it
DECLARE #urlpart nvarchar
set #urlpart='bol.com'
SET #urlpart = '%'+#urlpart + '%'
SELECT * FROM Brick
WHERE BrickUrl like #urlpart
written without parameter like this:
SELECT * FROM brick
WHERE BrickUrl like '%bol.com%'
returns the 6 rows containing bol.com correctly.
I can't figure out what the reason is, or what I do wrong, do you see it?

Try this:
DECLARE #urlpart nvarchar
set #urlpart='bol.com'
SET #urlpart = '%'+#urlpart + '%'
select #urlpart
Result:
(No column name)
%
and then you should try this instead
DECLARE #urlpart nvarchar(128)
set #urlpart='bol.com'
SET #urlpart = '%'+#urlpart + '%'
select #urlpart
Result;
(No column name)
%bol.com%
When not specifying the size of nvarchar you will get size 1.

Related

TSQL query to extract a value between to char where a specific set of characters is there

I have a problem I can't seem to figure out. I am trying to extract capacity from a product description. It is always between two values, "," and "oz." however there could be other commas included in the description that are not part of what I'm trying to extract. Example value is , 15 oz., or , 2 oz.,
I'm trying to find values that have the oz in them and are between two commas and I have been completely unsuccessfully. I've tried many things, but here is the latest that I have tried today and I'm just getting an error.
SELECT SUBSTRING(
FullDescription,
CHARINDEX(',', FullDescription),
CHARINDEX('oz.',FullDescription)
- CHARINDEX(',', FullDescription)
+ Len('oz.')
)
from CatalogManagement.Product
Since the backwards pattern ,.zo is more recognisable, I'd go with the REVERSE function
Sample values:
"something, something more, 18oz., complete"
"shorter, 12oz., remainder"
"there is no capacity, in this, value"
"a bit more, 14oz, and some followups, maybe"
SELECT REVERSE(
SUBSTRING (
REVERSE(FullDescription),
CHARINDEX(',.zo', REVERSE(FullDescription)) + 1,
CHARINDEX(',', REVERSE(FullDescription), CHARINDEX(',.zo', REVERSE(FullDescription)) + 1) - CHARINDEX(',.zo', REVERSE(FullDescription)) - 1
)
)
FROM CatalogManagement.Product
WHERE FullDescription LIKE '%oz.,%'
You might use XML-splitting together with a XQuery predicate:
DECLARE #tbl TABLE(ID INT IDENTITY, YourString VARCHAR(MAX));
INSERT INTO #tbl VALUES('Here is one with an amount, 1 oz., some more text')
,('Here is one with no amount, some more text')
,('a, 10 oz.')
,('b, 20oz., no blank between oz and the number')
,('30oz., starts with the pattern, no leading comma');
SELECT t.*
,A.oz.value('.','nvarchar(max)') oz
FROM #tbl t
CROSS APPLY(SELECT CAST('<x>' + REPLACE((SELECT t.YourString AS [*] FOR XML PATH('')),',','</x><x>') + '</x>' AS XML)
.query('/x[contains(text()[1],"oz.")]')) A(oz);
The idea in short:
We use some string methods to replace commas with XML tags and to cast your string to XML. each fragment is placed within a decent <x> element.
We use a predicate to return just the fragments containing "oz.".
You can filter easily with
WHERE LEN(A.oz.value('.','nvarchar(max)'))>0

How to find/replace weird whitespace in string

I find in my sql database string whit weird whitespace which cannot be replace like REPLACE(string, ' ', '') RTRIM and cant it even find with string = '% %'. This space is even transfered to new table when using SELECT string INTO
If i select this string in managment studio and copy that is seems is normal space and when everything is works but cant do nothing directly from database. What else can i do? Its some kind of error or can i try some special character for this?
First, you must identify the character.
You can do that by using a tally table (or a cte) and the Unicode function:
The following script will return a table with two columns: one contains a char and the other it's unicode value:
DECLARE #Str nvarchar(100) = N'This is a string containing 1 number and some words.';
with Tally(n) as
(
SELECT TOP(LEN(#str)) ROW_NUMBER() OVER(ORDER BY ##SPID)
FROM sys.objects a
--CROSS JOIN sys.objects b -- (unremark if there are not enough rows in the tally cte)
)
SELECT SUBSTRING(#str, n, 1) As TheChar,
UNICODE(SUBSTRING(#str, n, 1)) As TheCode
FROM Tally
WHERE n <= LEN(#str)
You can also add a condition to the where clause to only include "special" chars:
AND SUBSTRING(#str, n, 1) NOT LIKE '[a-zA-Z0-9]'
Then you can replace it using it's unicode value using nchar (I've used 32 in this example since it's unicode "regular" space:
SELECT REPLACE(#str, NCHAR(32), '|')
Result:
This|is|a|string|containing|1|number|and|some|words.

How to extract letters from a string using Firebird SQL

I want to implement a stored procedure that extract letters from a varchar in firebird.
Example :
v_accountno' is of type varchar(50) and has the following values
accountno 1 - 000023208821
accountno 2 - 390026826850868140H
accountno 3 - 0700765001003267KAH
I want to extract the letters from v_accountno and output it in o_letter.
In my example: o_letter will store H for accountno 2 and KAH for accountno 3.
I tried the following stored procedure, which obviously won't work for accountno 3. (Please help).
CREATE OR ALTER PROCEDURE SP_EXTRACT_LETTER
returns (
o_letter varchar(50))
as
declare variable v_accountno varchar(50);
begin
v_accountno = '390026826850868140H';
if (not (:v_accountno similar to '[[:DIGIT:]]*')) then
begin
-- My SP won't work in for accountno 3 '0700765001003267KAH'
v_accountno = longsubstr(v_accountno, strlen(v_accountno), strlen(v_accountno));
o_letter = v_accountno;
end
suspend;
end
One solution would be to replace every digits with empty string like:
o_letter = REPLACE(v_accountno, '0', '')
o_letter = REPLACE(o_letter, '1', '')
o_letter = REPLACE(o_letter, '2', '')
...
Since Firebird 3, you can use substring for this, using its regex facility (using the similar clause):
substring(v_accountno similar '[[:digit:]]*#"[[:alpha:]]*#"' escape '#')
See also this dbfiddle.

Using patterns in REPLACE

I need to find and replace an expression within a dynamic query. I have a subset of a where condition in string type like
'fieldA=23 OR field_1=300 OR fieldB=4'
What I need is to find a way to detect expression field_1=300 within the string and replace it while retaining the expression field_1=300.
I can do the detection part using CHARINDEX or PATINDEX but I'm not able to figure out how to use the patterns in the REPLACE function and how to get the value of the field_1 parameter.
Thanks in advance.
I'm not entirely clear on what you're trying to acheieve (e.g. what are you wanting to replace "field_1=300" with, and is it the exact string "field_1=300" that you're looking for, or just the field name, i.e. "field_1"?).
Also, could you paste in the code you've written so far?
Here's a simple script which will extract the current value of a given field name:
DECLARE #str VARCHAR(100),
#str_tmp VARCHAR(100),
#field_pattern VARCHAR(10),
#field_val INT;
SET #str = 'fieldA=23 OR field_1=300 OR fieldB=4';
SET #field_pattern = 'field_1='
-- This part will extract the current value assigned to the "#field_pattern" field
IF CHARINDEX(#field_pattern, #str) > 0
BEGIN
SELECT #str_tmp = SUBSTRING(#str,
CHARINDEX(#field_pattern, #str) + LEN(#field_pattern),
LEN(#str)
);
SELECT #field_val = CAST(SUBSTRING(#str_tmp, 1, CHARINDEX(' ', #str_tmp)-1) AS INT);
END
PRINT #field_val
If you want to replace the value itself (e.g. replacing "300" in this case with "600"), then you could add something like this:
DECLARE #new_val INT;
SET #new_val = 600;
SET #str = REPLACE(#str, (#field_pattern+CAST(#field_val AS VARCHAR)), (#field_pattern+CAST(#new_val AS VARCHAR)));
PRINT #str;
Which would give you "fieldA=23 OR field_1=600 OR fieldB=4".
Cheers,
Dave

IsDate in TSQL Issue

I have a bug on our app and it points that if there is a date format like this:
SELECT IsDate('4:27:01') -- ok
SELECT IsDate('25:01') ---> not ok
SELECT IsDate('23:01') ---> ok
In our data, sometimes the format only 5 characters which means it's only for minutes and seconds.
What is best way to handle this?
Easiest way might be to add "00:" when the length is 5 characters.
e.g. :
declare #str varchar(100)
set #str = '25:01'
-- if length is 5, interpret as 00:mi:ss
set #str = (CASE WHEN LEN(#str)=5 THEN '00:' + #str ELSE #str END)
select ISDATE(#str) -- shows 1
select cast(#str as time) -- shows 00:25:01.000