SQL Wildcard within data - sql

My situation is a bit odd. I have generated filenames inserted into a database that are to be matched with downloaded files later, however the downloaded files contain a random ID in the middle of their name.
If I include the wildcard characters on the generated filename that's inserted into the database, is there anyway to compare that against the actual downloaded file?
Generated name example: just-a-file-name-and-a-suffix.mp4
Actual downloaded file: just-a-file-name-51935-and-a-suffix.mp4
I have zero way to actually know what those 5 digits will be. I only know that there will be 5 digits. Ideally I'd insert the generated name into the database something like just-a-file-name-%-and-a-suffix.mp4 and use the LIKE keyword in a SQL query but it doesn't work that way.
Is there anything I can do to solve this and get a match?

you can use substring, replace and some other functions if you like.
Following is an example of using replace and creating a function for it.
`
CREATE Function [dbo].[RemoveNumericCharacters](#Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare #NumRange as varchar(50) = '%[0-9]%'
While PatIndex(#NumRange, #Temp) > 0
Set #Temp = Stuff(#Temp, PatIndex(#NumRange, #Temp), 1, '')
Return #Temp
End
and you can use it like so
SELECT dbo.RemoveNumericCharacters FROM TARGET_TABLE
`
taken from following post -- Remove numbers from string sql server
Note you be passing on your file string to the function and it will return the file name without the numbers in it.
Thanks

Related

How do you pass values for a parameter by position when you need to check multiple values?

I created a stored procedure (spBalanceRange) with 2 optional parameters. They've been set to a default value and the sp works fine when I pass only 1 value per parameter by position. However, I have a situation where I'm trying to pass, by position, two strings immediately followed by a wildcard. I want the user to be able to search for Vendor names that start with either 'C%' or 'F%'. Here's the gist of the CREATE PROC statement:
CREATE PROC spBalanceRange
#VendorVar varchar(40) = '%',
#BalanceMin money = 1.0
...
Here's what I've tried so far, but doesn't work:
EXEC spBalanceRange '(C%|F%)', 200.00;
EXEC spBalanceRange 'C%|F%', 200.00;
Is there a way to check for 2 or more string values with a wildcard when passed by position? Thanks.
EDIT: According to your comments you are looking for the first letter of a vendor's name only.
In this special case I could suggest an easy, not well performing but really simple approach. CHARINDEX returns a number greater than zero, if a character appears within a string. So you just have to pass in all your lookup-first-characters as a simple "chain":
DECLARE #DummyVendors TABLE(VendorName VARCHAR(100));
INSERT INTO #DummyVendors VALUES
('Camel Industries')
,('Fritz and Fox')
,('some other');
DECLARE #ListOfFirstLetters VARCHAR(100)='CF';
SELECT VendorName
FROM #DummyVendors AS dv
WHERE CHARINDEX(LEFT(dv.VendorName,1),#ListOfFirstLetters)>0
This was the former answer
Checking against more than one value needs either a dedicated list of compares
WHERE val=#prm1 OR val=#prm2 OR ... (you know the count before)
...or you use the IN-clause
WHERE LEFT(VenoderName,1) IN ('C','F', ...)
...but you cannot pass the IN-list with a parameter like ... IN(#allValues)
You might think about a created TYPE to pass in all your values like a table and use an INNER JOIN as filter: https://stackoverflow.com/a/337864/5089204 (and a lot of other examples there...)
Or you might think of dynamic SQL: https://stackoverflow.com/a/5192765/5089204
And last but not least you might think of one of the many split string approaches. This is one of my own answers, section "dynamic IN-statement": https://stackoverflow.com/a/33658220/5089204
I'm answering my own question, and maybe other solutions exist but here is what had to happen with my stored procedure in order to pass variables by position:
CREATE PROC spBalanceRange
#VendorVar varchar(40) = '%',
#BalanceMin money = 1.0
AS
IF (#VendorVar = '%' AND #BalanceMin IS NULL OR #BalanceMin = '')
BEGIN
PRINT 'BalanceMin cannot be null.';
END
IF (#VendorVar = % AND #BalanceMin IS NOT NULL)
BEGIN
(sql statement using parameters)
END
EXEC spBalanceRange '[C,F]%', 200.00;
That's what I know.

Renaming GUID that has hypens to underscores in SQL Server

SQL and trying for a solution.
Case:
Our System runs different Business process and outputs process result set into a new table called "Export_PROCESSSID". The ProcessID is GUID (XXX-XFG-EDRT ) but when the system creates the table it uses the ProcessID but rename it to (Export_XXX_XFG_EDRT). Hyphens are replaced with underscores and prefixed with "Export_".
Sofar:
First, I run a select statement to find the latest Process_ID in the table. Now I need to rename this GUID from this format "04ad20f5-3be6-481a-b341-d32f7702179f" to this "Export_04ad20f5_3be6_481a_b341_d32f7702179f".
Any ideas doing this t-sql with replace function or other methods? I am stuck here, any help will be appreciated. Many thanks.
I'm not sure what your context is, but this will transform XXX-XFG-EDRT into Export_XXX_XFG_EDRT:
'Export_' + REPLACE(ProcessID, '-', '_')
For neatness, convert your GUID into a varchar first, then run REPLACE on it:
DECLARE #guid uniqueidentifier
SET #guid = newid()
SELECT 'Export_' + REPLACE(CONVERT(varchar(50), #guid), '-', '_')
Returns (at least, the last time I ran it):
Export_8D997451_F7B6_4EC5_9CFC_478B7084811A

String update in SQL Server

Currently I have varchar field. The delimiter is "$P$P$".
The delimiter will appear at least once and at most twice in the varchar data.
Eg.
Sample Heading$P$P$Sample description$P$P$Sample conclusion
Sample Heading$P$P$Sample Description
If the delimiter appears twice, I need to insert a text before the second occurance of the delimiter.
Eg:
Sample Heading$P$P$Sample DescriptionINSERT TEXT HERE$P$P$Sample Conclusion
If the delimiter occurs only once, then I need to insert a text at the end of the field.
Eg:
Sample Heading$P$P$Sample DescriptionAPPEND TEXT HERE
How this can be done in SQL query?
If you are going to do a lot of string manipulation you might want to use a CLR (.net) function. Since SQL Server isn't exactly made for string manipulation.
Or even better, pull this data back to your application and do it in code.
I even think you can't do it using the default SQL Server String functions
The CharIndex function has an optional 3rd parameter that allows you to specify the starting position of the search. You can use this to find the 2nd occurrence of a string using CharIndex. You can also use the stuff function to insert a string in to another string.
Example:
Declare #Temp Table(Data VarChar(8000))
Insert Into #Temp Values('Sample Heading$P$P$Sample description$P$P$Sample conclusion')
Insert Into #Temp Values('Sample Heading$P$P$Sample Description')
Select len(Data),
CharIndex('$P$P$', Data + '$P$P$',CharIndex('$P$P$',Data) + 1),
Stuff(Data + ' ', CharIndex('$P$P$', Data + '$P$P$',CharIndex('$P$P$',Data) + 1), 0, 'Text Here')
From #Temp
I realize it looks like a mess, but I do encourage you to understand how this works because you may need something similar in the future.
instead of using delimiters, why not creating 3 columns or if you only want one --> an xml field?

how to write the store procedure for searching (CSV)?

how can i write the store procedure for searching particular string in a column of table, for given set of strings (CSV string).
like : select * from xxx where tags like ('oscar','rahman','slumdog')
how can i write the procedure for that combination of tags.
To create a comma seperated string...
You could then apply this list to Oded example to create the LIKE parts of the WHERE cluase on the fly.
DECLARE #pos int, #curruntLocation char(20), #input varchar(2048)
SELECT #pos=0
SELECT #input = 'oscar,rahman,slumdog'
SELECT #input = #input + ','
CREATE TABLE #tempTable (temp varchar(100) )
WHILE CHARINDEX(',',#input) > 0
BEGIN
SELECT #pos=CHARINDEX(',',#input)
SELECT #curruntLocation = RTRIM(LTRIM(SUBSTRING(#input,1,#pos-1)))
INSERT INTO #tempTable (temp) VALUES (#curruntLocation)
SELECT #input=SUBSTRING(#input,#pos+1,2048)
END
SELECT * FROM #tempTable
DR0P TABLE #tempTable
First off, the use of like for exact matches is sub-optimal. Might as well use =, and if doing so, you can use the IN syntax:
select * from xxx
where tags IN ('oscar', 'rahman', 'slumdog')
I am guessing you are not looking for an exact match, but for any record where the tags field contains all of the tags.
This would be something like this:
select * from xxx
where tags like '%oscar%'
and tags like '%rahman%'
and tags like '%slumdog%'
This would be not be very fast or performant though.
Think about moving this kind of logic into your application, where it is faster and easier to do.
Edit:
Following the comments - there are lots of examples on how to parse delimited strings out there. You can put these in a table and use dynamic sql to generate your query.
But, this will have bad performance and SQL Server will not be able to cache query plans for this kind of thing. As I said above - think about moving this kind of logic to application level.

What is the easiest way using T-SQL / MS-SQL to append a string to existing table cells?

I have a table with a 'filename' column.
I recently performed an insert into this column but in my haste forgot to append the file extension to all the filenames entered. Fortunately they are all '.jpg' images.
How can I easily update the 'filename' column of these inserted fields (assuming I can select the recent rows based on known id values) to include the '.jpg' extension?
The solution is:
UPDATE tablename SET [filename] = RTRIM([filename]) + '.jpg' WHERE id > 50
RTRIM is required because otherwise the [filename] column in its entirety will be selected for the string concatenation i.e. if it is a varchar(20) column and filename is only 10 letters long then it will still select those 10 letters and then 10 spaces. This will in turn result in an error as you try to fit 20 + 3 characters into a 20 character long field.
MattMitchell's answer is correct if the column is a CHAR(20), but is not true if it was a VARCHAR(20) and the spaces hadn't been explicitly entered.
If you do try it on a CHAR field without the RTRIM function you will get a "String or binary data would be truncated" error.
Nice easy one I think.
update MyTable
set filename = filename + '.jpg'
where ...
Edit: Ooh +1 to #MattMitchell's answer for the rtrim suggestion.
If the original data came from a char column or variable (before being inserted into this table), then the original data had the spaces appended before becoming a varchar.
DECLARE #Name char(10), #Name2 varchar(10)
SELECT
#Name = 'Bob',
#Name2 = 'Bob'
SELECT
CASE WHEN #Name2 = #Name THEN 1 ELSE 0 END as Equal,
CASE WHEN #Name2 like #Name THEN 1 ELSE 0 END as Similiar
Life Lesson : never use char.
I wanted to adjust David B's "Life Lesson". I think it should be "never use char for variable length string values" -> There are valid uses for the char data type, just not as many as some people think :)
The answer to the mystery of the trailing spaces can be found in the ANSI_PADDING
For more information visit: SET ANSI_PADDING (Transact-SQL)
The default is ANSI_PADDIN ON. This will affect the column only when it is created but not to existing columns.
Before you run the update query, verify your data. It could have been compromised.
Run the following query to find compromised rows:
SELECT *
FROM tablename
WHERE LEN(RTRIM([filename])) > 46
-- The column size varchar(50) minus 4 chars
-- for the needed file extension '.jpg' is 46.
These rows either have lost some characters or there is not enough space for adding the file extension.