Multiple word search in a single table column - c#

I am create a simple textbox that allow to single word compare into the table.
if i am give multiple keyword into the textbox only one word working on multiple text its not fetch record.
my database table is-
id text keyword
1 Somting with keyword1 & Keyword3 keyword1, keyword3
2 Somting with keyword2 & Keyword3 Keyword2, Keyword3
Search string is like-
What is Keyword3 with keyword1
Desired result is
Somting with keyword1 & Keyword3 show in record
using c# sql
I am trying
Create PROCEDURE [dbo].[spGetChatAutofill]
(
#term VARCHAR(255)
)
AS
begin
select id , text, keyword
from tbl
where keyword in (select keyword from fn_stringSplit(#term) ss where keyword like '%'+SplitValue+'%')
end
and for function-
ALTER function [dbo].[fn_stringSplit](#StringSplit varchar(max))
returns #table table(SplitValue varchar(10) not null)
as
begin
Declare #StartVal int
Declare #endVal int
set #StringSplit = #StringSplit + ' '
set #StartVal = 1
set #endVal = 1
while #endVal >= 0
begin
set #endVal = charindex(' ',#StringSplit,#StartVal);
insert into #table select SUBSTRING(#StringSplit,#StartVal,#endVal-1)
set #StringSplit= SUBSTRING(#StringSplit,#endVal+1, LEN(#StringSplit))
if #StringSplit = '' set #endVal= -1
end
return
end

First , Sql Server 2017 has STRING_SPLIT.
Search rows with all requested keywords present procedure.
Create PROCEDURE [dbo].[spGetChatAutofill]
(
#term VARCHAR(255)
)
AS
begin
select id, text, keyword
from tbl
where not exists(
select 1
from STRING_SPLIT(#term, ' ') terms
where tbl.keyword not like '%'+terms.value+'%')
end
Note this may match partial keywords. For example
a call with an argument "key word" will successfully find "keyword1, keyword2" in the table.

Related

Check if string is any combination of multiple word combinations saved in database

I have SQL Server database and application using EF. I want to check a list of word combinations as validation before proceeding with certain functionality.
Table in DB:
WordCombination
%lorem%ipsum%
...
I have the %lorem%ipsum% in the DB and want to check a string in the .NET application for likeness against it and get boolean result for example "ipsum lorem" should return TRUE
Currently I have
context.Table.Select(row=>row.WordCombination).Any(combination=>EF.Functions.Like(myString,combination))
notice I use the combination from the DB as a pattern
I try to make the solution as optimal as possible so I don't want to enumerate the table since it may have many rows and I don't want to add any duplicates. Also i try to get only the combination of the two so separating the entry in "lorem" and "ipsum" is not a variant for now.
Is there a way to find both "lorem ipsum","ipsum lorem" and other combinations like "ipsum1234lorem" without adding "ipsum%lorem" entry and without enumerating the table? (with just a query)
Thanks in advance.
Wouldn't the following work?
WHERE (YourColumn LIKE '%lorem%' AND YourColumn LIKE '%ipsum%')
OR YourColumn LIKE '%asdf%'
You could use a stored procedure like below:
ALTER PROCEDURE proc_MatchWordCombinations
#input NVARCHAR(MAX)
AS
BEGIN
DECLARE searchRows CURSOR
FOR SELECT * FROM WordCombinations;
DECLARE #searchRow NVARCHAR(MAX)
DECLARE #searchParts TABLE(RowID int not null primary key identity(1,1), searchPart NVARCHAR(MAX), processed BIT NOT NULL DEFAULT 0)
DECLARE #searchPart NVARCHAR(MAX)
DECLARE #searchPartID INT
DECLARE #partsToProcess INT
DECLARE #index INT
DECLARE #match BIT
OPEN searchRows
FETCH NEXT FROM searchRows INTO #searchRow
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT 'Search row: ' + #searchRow
DELETE FROM #searchParts
INSERT INTO #searchParts (searchPart)
SELECT value
FROM STRING_SPLIT(#searchRow, '%');
DELETE FROM #searchParts WHERE searchPart = ''
SELECT #partsToProcess = COUNT(1) FROM #searchParts
SET #index = 0
SET #match = 1
WHILE #index < #partsToProcess
BEGIN
SET #index = #index + 1
PRINT #index
SELECT TOP 1 #searchPart = searchPart, #searchPartID = RowID FROM #searchParts WHERE processed = 0
UPDATE #searchParts SET processed = 1 WHERE RowID = #searchPartID
PRINT 'Search part: ' + #searchPart
IF CHARINDEX(#searchPart, #input) = 0
BEGIN
SET #match = 0
PRINT 'No match: ' + #searchPart
END
ELSE
BEGIN
PRINT 'Match: ' + #searchPart
END
END
IF #match = 1
BEGIN
-- The input matches the search row
PRINT 'Match on: ' + #searchRow
END
FETCH NEXT FROM searchRows INTO #searchRow
END
CLOSE searchRows
DEALLOCATE searchRows
END
And call it like so:
EXEC proc_MatchWordCombinations #input = 'ipsum1234lorem'

How to create multiple tables dynamiclly in view by using following data in list

My requirement is to create multiple tables dynamic
here is part numbers .table number
1. table number 1 has 2 records and table number 2 has also 2 records.
firstly create table no. 1 and fill its records
after that create new second table no. 2 and its records and soo on according to table number
in some case i have only part no. but in this we create another something html in which we display those data which does not have table no.
Declare table variable to store id and tableNo.
declare #TempTable table(id int identity,TableNo int)
Insert into this table of all distinct TableNo column data..
INSERT INTO #TempTable
SELECT DISTINCT TabloNo
FROM TableName
Declare following variable and set its value like...
declare #counter int, #totalTable int, #NoOfTable int, #StrquryInser nvarchar(max)
select #totalTable = count(id) from #TempTable
set #counter = 1
set #StrquryInser = ''
In while block select table data according to tableNo and insert it into #temp1, #temp2...dynamically using this code...
begin
select #NoOfTable = TableNo
from #TempTable
where id = #counter
set #StrquryInser = #StrquryInser + ' select * into #temp' +cast(#counter as varchar(10)) + ' from TableName where isnull([TabloNo],0)='+cast(isnull(#NoOfTable,0) as nvarchar(10))
set #StrquryInser=#StrquryInser + ' select * from #temp' +cast(#counter as varchar(10))
set #counter=#counter+1
end
execute the string Query #StrquryInser like...
exec(#StrquryInser)
In above query you can store your table data in multiple temp variables like temp1, #temp2 etc..
Apart form these #temp table you can also store your data in permanent table using above logic..

How to use a set of strings in a WHERE statement of SQL?

Sorry i am not sure how to titled the question well. I want to select few records in sql where a particular column is a set of strings.
Example . I have a table student and has columns ID and name. ID has records 1,2,3,4,5,6 . NAme has A,B,C,D,E,F.
I want to return C,D,E WHERE ID=[3,4,5].
I tried
SELECT FROM student WHERE ID=2,3,4
it gives error, ID=2,3,4 ='2,3,4' and it reads ID as a single columns. I am confused.
Also in my case, ID set are returned in a storedprocedure variable. that is like #ID
SELECT * FROM STUDENT WHERE ID=#ID
#ID above is a variable of a string type holding the set {1,2,3}. Please any help would be appreciated.
Try this:
SELECT * FROM student WHERE ID IN (2,3,4)
Syntax:
test_expression IN
( subquery | expression [ ,...n ]
)
Read more about IN operator here.
WHERE ID=2,3,4 and WHERE ID='2,3,4' are invalid syntax for SQL.
Looks like you can use IN (Transact-SQL) on your situation.
Determines whether a specified value matches any value in a subquery
or a list.
SELECT FROM student WHERE ID IN (2, 3, 4)
Also you might take a look Jeff's question Parameterize an SQL IN clause
If you are passing #ID as a variable with comma separated list of ids, WHERE IN (#ID) will not work.
I think best thing would be to use a Table Valued function to split them first and then query the table. Please check here for a Split() function.
Usage:
SELECT * FROM STUDENT
WHERE ID IN (
SELECT items FROM dbo.Split(#ID, ',') --Split function here
)
If you want to fitler multiple values in Select, you should use "in ()":
SELECT * FROM student WHERE ID in (2,3,4)
OR
SELECT * FROM student WHERE ID between 2 and 4
OR
SELECT * FROM student WHERE ID = 2 OR ID = 3 OR ID = 4
In this case take the first one.
The last one is very slow and not recommended in this scenario.
Please check this out
Select * from Student where Id IN ('2','3','4')
and check this out
Select Username from Student where ID IN ' + '('+ #Id +')'
where #Id=2,3,4
Select * from Student where Id='2'
union all
Select * from Student where Id='3'
union all
Select * from Student where Id='4'
Based on your comment below, you don't want to convert ID to an int. Instead, use LIKE to compare:
SELECT * from STUDENT
WHERE ', '+#ID+', ' LIKE ', '+CAST(ID as NVARCHAR(255)) + ', ';
However, the query will not be indexed. If you want the query to be indexed, then use dynamic SQL:
DECLARE #query NVARCHAR(max) = 'SELECT * FROM STUDENT WHERE ID IN ('+ #ID +')';
EXEC sp_executesql #query;
Since you are using Stored Procedure, that also has only equality compare i.e. id = 1, so either you have too execute three queries by splitting the input by comma separated values.
OR you can add a new procedure with a custom function to server with the SQL
CREATE FUNCTION dbo.myparameter_to_list (#parameter VARCHAR(500)) returns #myOutput TABLE (mytempVal VARCHAR(40))
AS
begin
DECLARE #TempTable table
(
mytempVal VARCHAR(40)
)
DECLARE #MySplittedValue varchar(40), #PositionOfComma int
SET #par = LTRIM(RTRIM(#parameter))+ ','
SET #PositionOfComma = CHARINDEX(',', #parameter, 1)
IF REPLACE(#parameter, ',', '') <> ''
BEGIN
WHILE #PositionOfComma > 0
BEGIN
SET #MySplittedValue = LTRIM(RTRIM(LEFT(#par, #PositionOfComma - 1)))
IF #MySplittedValue <> ''
BEGIN
INSERT INTO #TempTable (mytempVal) VALUES (#MySplittedValue) --Use conversion if needed
END
SET #par = RIGHT(#par, LEN(#par) - #PositionOfComma)
SET #PositionOfComma = CHARINDEX(',', #par, 1)
END
END
INSERT #myOutput
SELECT mytempVal
FROM #TempTable
RETURN
END
In your stored procedure you would use it like this:
Create Procedure StudentSelectFromSet
#Ids VARCHAR(MAX)
AS
SELECT * FROM student Stud
WHERE Stud.Id IN(SELECT value FROM dbo.myparameter_to_list (#Ids))
and then execute this new procedure as you were accessing earlier.

Query to MySQL from c# returns System.Byte[]

I am using the below SP to return the value of Generated Insert statement and it works fine when executed in Query browser.
When i try to get the value from C#, it give's me "System.Byte[]" as return value.
When i try to get the value from MySql query browser, it give's me return value as :
'insert into admindb.accounts values("54321","2","karthik2","karthik2","1");'
I guess the problem is with the single quotes of the returned value. Is it so ?
DELIMITER $$
DROP PROCEDURE IF EXISTS `admindb`.`InsGen` $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `InsGen`(
in_db varchar(20),
in_table varchar(20),
in_ColumnName varchar(20),
in_ColumnValue varchar(20)
)
BEGIN
declare Whrs varchar(500);
declare Sels varchar(500);
declare Inserts varchar(2000);
declare tablename varchar(20);
declare ColName varchar(20);
set tablename=in_table;
# Comma separated column names - used for Select
select group_concat(concat('concat(\'"\',','ifnull(',column_name,','''')',',\'"\')'))
INTO #Sels from information_schema.columns where table_schema=in_db and table_name=tablename;
# Comma separated column names - used for Group By
select group_concat('`',column_name,'`')
INTO #Whrs from information_schema.columns where table_schema=in_db and table_name=tablename;
#Main Select Statement for fetching comma separated table values
set #Inserts=concat("select concat('insert into ", in_db,".",tablename," values(',concat_ws(',',",#Sels,"),');')
as MyColumn from ", in_db,".",tablename, " where ", in_ColumnName, " = " , in_ColumnValue, " group by ",#Whrs, ";");
PREPARE Inserts FROM #Inserts;
EXECUTE Inserts;
END $$
DELIMITER ;
Adding this in connection settings did the trick : respect binary flags=false;

SQL Server (2008) Pass ArrayList or String to SP for IN()

I was wondering how I can pass either an ArrayList, List<int> or StringBuilder comma delimited list to a stored procedure such that I find a list of IDs using IN():
#myList varchar(50)
SELECT *
FROM tbl
WHERE Id IN (#myList)
In C# I am currently building the list as a string which is comma delimeted; however when using nvarchar(50) for example, as the type for the param in the stored procedure - I get an error as it can't convert '1,2,3' to int which it expects between the IN().
Any ideas? Much appreciated.
Pete
You could use a User Defined function such as
CREATE function [dbo].[csl_to_table] ( #list nvarchar(MAX) )
RETURNS #list_table TABLE ([id] INT)
AS
BEGIN
DECLARE #index INT,
#start_index INT,
#id INT
SELECT #index = 1
SELECT #start_index = 1
WHILE #index <= DATALENGTH(#list)
BEGIN
IF SUBSTRING(#list,#index,1) = ','
BEGIN
SELECT #id = CAST(SUBSTRING(#list, #start_index, #index - #start_index ) AS INT)
INSERT #list_table ([id]) VALUES (#id)
SELECT #start_index = #index + 1
END
SELECT #index = #index + 1
END
SELECT #id = CAST(SUBSTRING(#list, #start_index, #index - #start_index ) AS INT)
INSERT #list_table ([id]) VALUES (#id)
RETURN
END
Which accepts an nvarchar comma separated list of ids and returns a table of those ids as ints. You can then join on the returned table in your stored procedure like so -
DECLARE #passed_in_ids TABLE (id INT)
INSERT INTO #passed_in_ids (id)
SELECT
id
FROM
[dbo].[csl_to_table] (#your_passed_in_csl)
SELECT *
FROM
myTable
INNER JOIN
#passed_in_ids ids
ON
myTable.id = ids.id
In SQL 2008 there are table-valued-parameters, that make a friendly alternative to parsing CSV; see here for an example.
Otherwise, another option is xml - the xml data type in SQL Server allows you to read this pretty easily (although it takes more transfer bytes).

Categories

Resources