I have a table which contains a column named NUMBERS which has the values 1234, 1235, 1278, 4567, 5434, and 7890. I am trying to write a procedure that will SELECT all values that begin with a number #NUMBER.
I was thinking it would look something like this:
DECLARE #NUMBER as int
SET #NUMBER = 1
SELECT * FROM table1 WHERE [NUMBER] LIKE (#NUMBER + '%')
But that is giving me an error 'Conversion failed when converting the varchar value '%' to data type int'.
How can I make it so that if I enter 1 as my #NUMBER it will return everything that begins with 1 (i.e. 1234, 1235, 1278)
You need to convert numbers to strings so the + operator is understood to be string concatenation (rather than addition):
SELECT *
FROM table1
WHERE cast([NUMBER] as varchar(255)) LIKE cast(#NUMBER as varchar(255)) + '%';
Because like does an implicit cast() anyways, you should be explicit about what the query is doing. I add a cast to the first part as well.
Note: You could also fix this by changing the declaration of the variable:
DECLARE #NUMBER as varchar(255);
SET #NUMBER = '1';
SELECT * FROM table1 WHERE [NUMBER] LIKE (#NUMBER + '%');
Related
Got a table that contains a field similar to the following
856655.460000000000000+0.000000000000000+2200121.020000000000000
164171.720000000000000+0.000000000000000+421637.020000000000000
0.000000000000000+0.000000000000000+0.000000000000000+0.000000000000000
103176.220000000000000+0.000000000000000+264984.210000000000000
What I need to do is extract the numeric fields and total them. There may be a different number of numeric fields within the column, but they'll all be separated by the '+' symbol
Any help would be appreciated
Try this. to get a better answer you should add more detail about how the table is structured.
DECLARE #val VARCHAR(MAX) = '856655.460000000000000+0.000000000000000+2200121.020000000000000+164171.720000000000000+0.000000000000000+421637.020000000000000+0.000000000000000+0.000000000000000+0.000000000000000+0.000000000000000+103176.220000000000000+0.000000000000000+264984.210000000000000';
DECLARE #newVal VARCHAR(MAX);
CREATE TABLE #Table
(
value DECIMAL(30, 15)
);
WHILE LEN(#val) > 0
BEGIN
IF(#val LIKE '%+%')
BEGIN
SET #newVal = LEFT(#val, CHARINDEX('+', #val));
INSERT INTO #table
VALUES
(
CONVERT( DECIMAL(30, 15), LEFT(#newVal, LEN(#newVal) - 1))
);
SET #val = SUBSTRING(#val, LEN(#newVal)+1, LEN(#Val)-LEN(#newVal));
END;
ELSE
BEGIN
INSERT INTO #Table
VALUES
(
CONVERT( DECIMAL(30, 15), REPLACE(#val, '+', ''))
);
SET #val = '';
END;
END;
SELECT * FROM #Table
SELECT sum(value) FROM #Table;
DROP TABLE #Table
Edit:
To retrofit this to work on a table you could add a cursor which loops through each row in your table, runs the above query and updates the table with the results from the sum. I'm sure there are better ways but if this is a one time cleanup, it should work. Cheers
Clearly you will have to modify this to fit your situation, but the basic concept is to transform your plus sign separated string into xml and then use the nodes method to break it apart.
IF OBJECT_ID('tempdb..#temp', 'U') IS NOT NULL DROP TABLE #temp;
declare #string varchar(250)
declare #xml xml
set #string = '856655.460000000000000+0.000000000000000+2200121.020000000000000'
set #xml = ('<r>' + REPLACE(#string,'+','</r><r>') + '</r>')
select t.v.value('r[1]', 'decimal(25,15)') as Value1,
t.v.value('r[2]', 'decimal(25,15)') as Value2,
t.v.value('r[3]', 'decimal(25,15)') as Value3,
t.v.value('r[4]', 'decimal(25,15)') as Value4
into #temp
from #xml.nodes('/') AS t(v)
select *
from #temp
select coalesce(Value1, 0) + coalesce(Value2, 0) +
coalesce(Value3, 0) + coalesce(Value4, 0) as 'Total'
from #temp
You will have to add more code to the query that selects into #temp for each potential value in your string. If you have a massive amount of possible numbers this may not scale.
Hope this helps you get to what you need.
I have a text field in my database:
DECLARE #vchText varchar(max) =
This is a string<>Test1<>Test2<>Test
That #vchText parameter should return like this:
This is a string:
1. Test1
2. Test2
3. Test
Anyone think of a good way to correct this. I was thinking the STUFF and CHARINDEX Functions with a WHILE LOOP...?
Something I should also note would be that there might not be only 1,2,3 items in the list there could be lots more so I can't build it so its static and only handles 1,2,3 it should be able to work for any number of items in the list.
Try this. Break the string into parts.
First part - This is a list:
Second part - 1.Test1 1.Test2 1.Test3
Convert the second part into rows using the delimiter Space. Then add row_number to the rows. Append the row_number and column data.
Finally convert the different rows into single row delimited by space and append it with the first part
DECLARE #NOTE VARCHAR(max) = 'This is a list: 1.Test1 1.Test2 1.Test3',
#temp VARCHAR(max),
#output VARCHAR(max)
SELECT #temp = Substring(#NOTE, Charindex(':', #NOTE) + 2, Len(#note))
SELECT #output = LEFT(#NOTE, Charindex(':', #NOTE) + 1)
SELECT #output += CONVERT(VARCHAR(10), Row_number() OVER (ORDER BY col))
+ Substring(col, Charindex('.', col), Len(col))
+ ' '
FROM (SELECT Split.a.value('.', 'VARCHAR(100)') col
FROM (SELECT Cast ('<M>' + Replace(#temp, ' ', '</M><M>') + '</M>' AS XML) AS Data) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)) ou
SELECT #output -- This is a list: 1.Test1 2.Test2 3.Test3
I was able to do it with a loop and use the stuff and charindex below.
DECLARE #vchText varchar(max) =
This is a string<>Test1<>Test2<>Test
DECLARE #positionofNextX INT = CHARINDEX('<>', #vchText)
DECLARE #nbrOFListItems INT = 1
WHILE #positionofNextX != 0
BEGIN
SET #NOTE = STUFF( #vchText, #positionofNextX, 4, CAST(#nbrOFListItems AS VARCHAR(1)) + '. ')
SET #positionofNextX = CHARINDEX('<>', #vchText)
--increment the list item number
SET #nbrOFListItems = #nbrOFListItems + 1
END
print #vchText
I have a space separated string as parameter to my SP. I need to split the strings and compare each one against a column in the database along with wildcard and return the results.
For example:
I have CompanyName 'ABC DataServices Pvt Ltd' I need to split the string by 'space' and compare each word with database field company name with an OR condition.
Something like this:
select *
from CompanyTable
where companyname like '%ABC%'
or companyname like '%DataServices%'
or companyname like '%Pvt%'
or companyname like '%Ltd%'
Can some one help me out to achieve this?
Thanks in advance
Try this SQL User Defined Function to Parse a Delimited String helpful .
For Quick Solution use this ,
SELECT PARSENAME(REPLACE('ABC DataServices Pvt Ltd', ' ', '.'), 2) // return DataServices
PARSENAME takes a string and splits it on the period character. It takes a number as it's second argument, and that number specifies which segment of the string to return (working from back to front).
you can put the index you want in place of 2 in above like
SELECT PARSENAME(REPLACE('ABC DataServices Pvt Ltd', ' ', '.'), 3) --return Pvt
declare a string in your store procedure and use set this value to it. use where you want.
The only problem is when the string already contains a period. One thing should be noted that PARSENAME only expects four parts, so using a string with more than four parts causes it to return NULL
Try this function:
CREATE FUNCTION [dbo].[fnSplitString]
(
#string NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE #start INT, #end INT
SELECT #start = 1, #end = CHARINDEX(#delimiter, #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(#delimiter, #string, #start)
END
RETURN
END
And use it like this:
select * from dbo.fnSplitString('Querying SQL Server','')
This will scale to any number of search terms and does not require dynamic SQL.
declare #a table (w varchar(50)) -- holds original string
declare #b table (s varchar(50)) -- holds parsed string
insert into #a -- load string into temp table
values ('ABC DataServices Pvt Ltd')
--parse string as XML
;WITH Vals AS (
SELECT w,
CAST('<d>' + REPLACE(w, ' ', '</d><d>') + '</d>' AS XML) XmlColumn
FROM #a
)
--Insert results to parsed string
insert into #b
SELECT
C.value('.','varchar(max)') ColumnValue
FROM Vals
CROSS APPLY Vals.XmlColumn.nodes('/d') AS T(C)
--Join on results
select * from companytable
join #b b on b.s like '%'+companyname+'%'
You can also try this.
First in your parameter's value replace space with comma (,) and then replace comma with desired where condition like this -
DECLARE #companyname VARCHAR(1000)
,#where VARCHAR(max)
SET #companyname = 'ABC DataServices Pvt Ltd'
SET #companyname = replace(#companyname, ' ', ', ')
SELECT #where = 'companyname like ''%' +
REPLACE(#companyname, ', ', '%'' OR companyname like ''%') + '%'''
PRINT #where
PRINT ('SELECT * FROM CompanyTable WHERE' + #where)
--EXEC ('SELECT * FROM CompanyTable WHERE' + #where)
I have a column in table which has following values. Names are separed by comma..
ProjID Names
1 Adam , Babita Tripathy, Alex, Mihir , Farhad
2 SaravanaKumar, Shruthi, Arthi, Suneeth
I am passing input value to stored procedure to fetch values. The input value is multiple names. If input is (Arthi,SaravanaKumar) i need to get both the rows as result because ProjID 1 and 2 has one of the input names. How can i achive it. Please help..
Search Condition.
IF #Names<>''
SET #condition = #condition+' ProdType.NamesLIKE'''+'%'+RTRIM(#Names)+'%'' AND'
You can use a function to split he input string
IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID('UF_CSVToTable'))
DROP FUNCTION UF_CSVToTable
GO
CREATE FUNCTION UF_CSVToTable
(
#psCSString VARCHAR(8000)
)
RETURNS #otTemp TABLE(sID VARCHAR(MAX))
AS
BEGIN
DECLARE #sTemp VARCHAR(10)
DECLARE #tTemp VARCHAR(10)
WHILE LEN(#psCSString) > 0
BEGIN
SET #sTemp = LEFT(#psCSString, ISNULL(NULLIF(CHARINDEX(',', #psCSString) - 1, -1),
LEN(#psCSString)))
SET #psCSString = SUBSTRING(#psCSString,ISNULL(NULLIF(CHARINDEX(',', #psCSString), 0),
LEN(#psCSString)) + 1, LEN(#psCSString))
INSERT INTO #otTemp(sID) VALUES (#sTemp)
END
RETURN
END
Go
It can be called like this.
select * from UF_CSVToTable('1,2,3,4,5,6,7,15,55,59,86')
SQL FIDDLE DEMO
MY Table like this:
id Tag platform
1 #class1,#class2 CS
2 #class1 PS
3 #class2 CS
if i pass "'#class1'" as parameter to SP getting only one record that is 2nd record.But need to 1st and 2nd records because #class1 contains in both 1,2 rows.Please tell me how to write this.I am using IN statement as of now.By using getting only record.
MY SP:
ALTER PROCEDURE [dbo].[usp_Get]-- 1,"'#class1,#class2'"
#Appid INT,
#TagList NVARCHAR (MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT #TagList = '%' + RTRIM(LTRIM(#TagList)) + '%';
declare #tags varchar(MAX)
set #tags = #TagList
create table #t (tag varchar(MAX))
set #tags = 'insert #t select ' + replace(#tags, ',', ' union select ')
exec(#tags)
Select
id FROM dbo.List WHERE ((appid=#Appid)) AND ((Tags LIKE(select tag from #t)
END
How to modify please tell me...
Thanks in advance..
One solution would be to use LIKE operator in your stored procedure:
CREATE PROCEDURE FindTag #TagName char(50)
AS
SELECT #TagName = '%' + TRIM(#TagName) + '%';
SELECT Tag
FROM MyTable
WHERE Tag LIKE #TagName;
GO