I trying to use list of numbers like this.
SELECT *
FROM users
WHERE id in (list_of_ids)
this is part of sql procedure and the variable 'list_of_ids' is varchar and it contains id's like this: 1,2,3,4,5........
How can i use this list and this query
Try this as well. This could be the better solution as it wont require any additional function to create.
oracle regexp_substr will split comma seperated values into different rows and passes to query.
SELECT *
FROM users
WHERE id in
(SELECT regexp_substr(list_of_ids,'[^,]+', 1, level) FROM dual
connect by regexp_substr(list_of_ids, '[^,]+', 1, level) is not NULL)
You can use a ref cursor to construct the sql query, as in this pl/sql block:
declare
list_of_ids varchar2(100) := '1,3,4'; -- example
c_cursor sys_refcursor;
result number;
begin
open c_cursor for ( 'SELECT id '||
'FROM users '||
'WHERE id in ('||list_of_ids||')'
);
fetch c_cursor into result;
while c_cursor%found
loop
dbms_output.put_line('ID='||to_char(result));
fetch c_cursor into result;
end loop;
close c_cursor;
end;
/
Try this solution in your project.
Add a new user function that returns a table.
Code is below:
CREATE FUNCTION [dbo].[fn_Split](#text varchar(8000), #delimiter
varchar(20) = ' ')
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
And then call it from your stored procedure like below.
DECLARE #list_of_ids AS VARCHAR(100)
SET #list_of_ids = '1,2,3,4,5,6,7,8,9,10,'
SELECT *
FROM users
WHERE id in (SELECT value FROM dbo.fn_Split(#list_of_ids,','))
Related
I have a emailID column in my database .Which has some numeric value in starting followed by 3 dashes then comes emailID I want to remove the numberic values as well as 3 dashes. which are coming starting from the emailID . The numeric values can be increase or decrease but dashes will remain same.below are the examples
dbo.regexp_replace('128888822229990976---Anand.chaudhary#gmail.com','^(\d+\-{3})','') as email_guess1
dbo.regexp_replace('222299---Anand.chaudhary#gmail.com','^(\d+\-{3})','') as email_guess1
dbo.regexp_replace('45390976---Archit.kumar-bhargav#gmail.com','^(\d+\-{3})','') as email_guess1
dbo.regexp_replace('0042352229990976---shiv.mangal-gupta#gmail.com','^(\d+\-{3})','') as email_guess1
I am using below user defined function its working fine but taking more time because my table has millions of records .. Please help me.
CREATE function [dbo].[regexp_replace] (
--
--
-- These match exactly the parameters of RegExp
--
#searchstring varchar(4000),
#pattern varchar(4000),
#replacestring varchar(4000)
)
returns varchar(4000)
as
begin
declare #objRegexExp int,
#objErrorObj int,
#strErrorMessage varchar(255),
#res int,
#result varchar(4000)
if #searchstring is null or len(ltrim(rtrim(#searchstring))) = 0 begin
return null
end;
set #result='';
exec #res = sp_OACreate 'VBScript.RegExp', #objRegexExp out;
if #res <> 0 begin
return 'VBScript did not initialize!';
end;
exec #res=sp_OASetProperty #objRegexExp, 'Pattern', #pattern;
if #res <> 0 begin
return 'Pattern property set failed!';
end;
exec #res=sp_OASetProperty #objRegexExp, 'IgnoreCase', 0;
exec #res=sp_OASetProperty #objRegexExp, 'global', 1;
if #res <> 0 begin
return 'IgnoreCase option failed!';
end;
exec #res=sp_OAMethod #objRegexExp, 'Replace', #result out, #searchstring, #replacestring;
if #res <> 0 begin
return 'Bad search string!';
end;
exec #res=sp_OADestroy #objRegexExp;
return #result
end;
It is too expensive to use VB COM objects in your queries.
Here you can use RIGHT, LEN and CHARINDEX to achieve that:
CREATE TABLE t (email varchar(100)) ;
INSERT INTO t (email)
VALUES ('123---Anand.chaudhary#gmail.com') ;
SELECT RIGHT(email, LEN(email) - CHARINDEX('---', email) - 2) as email
FROM t ;
So your function would be:
CREATE function [dbo].[fn_email] (
#email varchar(200), -- I beleive there won't be email addresses longer than 200 chars
)
returns varchar(200)
as
begin
SELECT RIGHT(#email, LEN(#email) - CHARINDEX('---', #email) - 2)
end
I want to find records using like query but in reverse mode
For exa: I have one string ts5e434
And now in databse I have one column called geohash and its contan comma seperated values
1) "ts5e4,ts5,ts5e434"
2) "ab,ye"
3) "ts,thh"
4) "t"
So here I want to get 1, 3 and 4 no records because its partially matching string
exa like clause
SELECT
*
FROM
service_geohashes
WHERE
'ts5e434' LIKE geohashes
Can anyone help me
Thanks in advance
I created function "LikeAny" in MSSQL which looks like:
CREATE FUNCTION [dbo].[LikeAny](#text nvarchar(MAX), #delimiter varchar(20), #comparestring nvarchar(MAX))
RETURNS BIT AS
BEGIN
DECLARE #LikeAny BIT = 0,
#TempString nvarchar(MAX)
DECLARE MY_CURSOR CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT value FROM STRING_SPLIT(#text, #delimiter)
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO #TempString
WHILE ##FETCH_STATUS = 0
BEGIN
--Do something with Id here
IF (#TempString <> '' AND #comparestring LIKE N'%' + #TempString + '%')
BEGIN
SET #LikeAny = 1
BREAK;
END
ELSE
FETCH NEXT FROM MY_CURSOR INTO #TempString
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
RETURN #LikeAny
END
If you use this in your example, it should look like:
SELECT
*
FROM
service_geohashes
WHERE
[dbo].[LikeAny](geohashes ,',', 'ts5e434') = 1
I tried also to convert the function above into MySQL but I had no option to test it on real environment
it looks like:
DROP FUNCTION IF EXISTS LikeAnyCommaDelimited;
DELIMITER $$
CREATE FUNCTION LikeAnyCommaDelimited(p_text longtext, p_comparestring longtext)
RETURNS TINYINT
DETERMINISTIC
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_LikeAny TINYINT DEFAULT 0;
DECLARE v_TempString longtext;
DECLARE v_SQL longtext;
drop temporary table if exists tempa;
drop temporary table if exists tempb;
CREATE TEMPORARY TABLE tempa( txt text );
CREATE TEMPORARY TABLE tempb( val char(255) );
insert into tempa values(p_text);
set v_SQL = concat("insert into tempb (val) values ('", replace(( select group_concat(distinct txt) as data from tempa), ',', "'),('"),"');");
prepare statement1 from #sql;
execute statement1;
DEClARE split_cursor CURSOR FOR
SELECT value FROM (select distinct(val) as value from tempb);
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN split_cursor;
get_string: LOOP
FETCH split_cursor INTO v_TempString;
IF v_finished = 1 THEN
LEAVE get_string;
END IF;
IF (v_TempString <> '' AND p_comparestring LIKE N'%' + CONCAT(v_TempString , '%') THEN
BEGIN
SET v_LikeAny = 1;
LEAVE get_string;
END
END LOOP get_string;
CLOSE split_cursor;
END$$
DELIMITER ;
Let me know if you have any issues.
I have Product table and has values for category path as "2210>2215>2219" and so on. Where 2210, 2215, 2219 are category Ids from Category table.
Few of the categories are inactive in database which is maintained at Category table.
To find products with inactive category in category path, I wish to write a query.
I wish to do something like this:
select p.* from product p, category c
where c.categoryId in (split(p.categoryPath,'>'));
which should basically, split category path by '>' and return me few strings to be passed in 'in'.
Is there any way where I can split this and get separate strings to be passed in in clause for above query?
Try this
create a function
CREATE FUNCTION [dbo].[fn_Split](#text varchar(8000), #delimiter varchar(20))
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
Sql query would be
select p.* from product p, category c
where c.categoryId in (select value from fn_split(p.categoryPath,'>'));
I want to write a stored procedure in which I want to run a query for multiple input which comes as a comma separated string. Just like we have in for exact match, can I have something like in too?
Input:
51094,51096,512584
Attempting to do:
select * from table where column like ('%51094%','%51096%','%512584%')
My query should iterate through each input and get the column which matches the pattern.
I have already tried following:
Contains(Column, '"*51094*" or "*51096*" or "*512584*")
But can't configure freetext search now.
Source: Is there a combination of "LIKE" and "IN" in SQL?
All the proposed types in: How to use SQL LIKE condition with multiple values in PostgreSQL?
None seems to be working.
Please suggest a simple way.
Try with first explode your input
$arr = explode($Input,",");
column like "%".$arr[0]."%" OR
column like "%".$arr[1]."%" OR
column like "%".$arr[2]."%"
This function you can use, no any mandatory to give comma only you can give special character.
ALTER function [dbo].[SplitString] (#String nvarchar(4000), #Delimiter char(1))
Returns #Results Table (Items nvarchar(50))
As
Begin
Declare #Index int
Declare #name nvarchar(20)
Declare #Slice nvarchar(50)
Select #Index = 1
If #String Is NULL Return
While #Index != 0
Begin
Select #Index = CharIndex(#Delimiter, #String)
If #Index <> 0
Select #Slice = left(#String, #Index - 1)
else
Select #Slice = #String
Insert into #Results(Items) Values (#Slice)
Select #String = right(#String, Len(#String) - #Index)
If Len(#String) = 0 break
End
Return
End
Looped the items and got it done.
Select * into #temp_inputIds from dbo.Split(#InputIds,',')
DECLARE #ID varchar (50)
DECLARE IDs CURSOR LOCAL FOR select items from #temp_inputIds
OPEN IDs
FETCH NEXT FROM IDs into #ID
WHILE ##FETCH_STATUS = 0
BEGIN
Select #SQL = 'Select component_id,'+#ID+' as pub_id from component_presentations where CONTENT like ''%' + #ID + '%'''
FETCH NEXT FROM IDs into #ID
END
CLOSE IDs
DEALLOCATE IDs
The user selects various words from a drop down list and these values get added into a comma delimited string. When passing the string to a stored procedure I want it to select * from a table where that word exists.
Table
id----word
1-----cat
2-----dog
3-----mouse
4-----dog
string that is passed into the stored procedure is cat, dog so returning columns 1, 2 and 4.
Is there a way of doing this in sql server?
Use IN:
SELECT *
FROM your_table
WHERE word IN ('cat', 'dog')
you first need to make a function SplitCSV :
CREATE FUNCTION [dbo].[SplitCSV] (#CSVString VARCHAR(8000), #Delimiter CHAR(1))
RETURNS #temptable TABLE (items VARCHAR(8000))
AS
BEGIN
DECLARE #pos INT;
DECLARE #slice VARCHAR(8000);
SELECT #pos = 1;
IF LEN(#CSVString) < 1 OR #CSVString IS NULL RETURN;
WHILE #pos!= 0
BEGIN
SET #pos = CHARINDEX(#Delimiter,#CSVString);
IF #pos != 0
SET #slice = LEFT(#CSVString, #pos - 1);
ELSE
SET #slice = #CSVString;
IF( LEN(#slice) > 0)
INSERT INTO #temptable(Items) VALUES (#slice);
SET #CSVString = RIGHT(#CSVString, LEN(#CSVString) - #pos);
IF LEN(#CSVString) = 0 BREAK;
END
RETURN
END
GO
then you can use it like :
SELECT *
FROM myTable
WHERE ID IN (
SELECT items FROM [dbo].[SplitCSV]('1,2,3,4,5', ',')
)
SELECT *
FROM Table
WHERE '%,' + Word + ',%' LIKE ',' + #your_csv_param + ','
Extra commas at the begin and end of parameter and column are to prevent search to match cat with catfish for example.
If you want select all animal except mouse , you can use NOT IN
SELECT * FROM
TABLE
WHERE Word Not IN('Mouse')
So you can avoid type many type of animal
CREATE FUNCTION
ALTER FUNCTION [dbo].[fn_Split](#text varchar(8000), #delimiter varchar(20) = ' ')
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
----
select * from yourtable where column in ( select value from fn_Split(#para1,',')