我有一个字符串,可以包含任何数量的空格分隔的单词。我通过sqlCommand将这个字符串作为参数从vb发送到sql。我怎样才能把它分解成一个数组在sql中或者将它作为数组从vb中一起发送来搜索表。如何通过存储过程中的数组进行搜索?
sql搜索必须返回所有那些行中的每一行都包含我传递的字符串中的所有单词。
我有一个字符串,可以包含任何数量的空格分隔的单词。我通过sqlCommand将这个字符串作为参数从vb发送到sql。我怎样才能把它分解成一个数组在sql中或者将它作为数组从vb中一起发送来搜索表。如何通过存储过程中的数组进行搜索?
sql搜索必须返回所有那些行中的每一行都包含我传递的字符串中的所有单词。
Using connection As New SqlConnection(connectionString)
Dim command As New SqlCommand("sp_GetCustomerByIDS", connection)
command.CommandType = System.Data.CommandType.StoredProcedure
'Here is how you pass in YourString seperated with comma's
command.Parameters.AddWithValue("@CustomerIDS", YourString.Replace(" ", ","))
...
End Using
值的逗号分隔的字符串被传递到存储过程(提示:请改变NTEXT作为SQL2005/SQL2008 +有VARCHAR(MAX)) :
CREATE PROCEDURE [dbo].[sp_GetCustomerByIDS]
@CustomerIDS ntext
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @err int
declare @TempTbl as TABLE(mystrings nvarchar(32), i1 int, i2 int, i3 int)
INSERT @TempTbl exec @err = sp_SplitTextList @CustomerIDS, ','
SELECT *
FROM dbo.Customers
WHERE
dbo.Customers.ID in (select mystrings from @TempTbl)
END
我用这个SplitTextList存储过程来处理逗号分隔值s,再次您可能需要将@list_text从文本更改为varchar(MAX),您可以从历史记录中看到其相当古老:
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-- uspSplitTextList
--
-- Description:
-- splits a separated list of text items and returns the text items
--
-- Arguments:
-- @list_text - list of text items
-- @Delimiter - delimiter
--
-- Notes:
-- 02/22/2006 - WSR : use DATALENGTH instead of LEN throughout because LEN doesn't count trailing blanks
--
-- History:
-- 02/22/2006 - WSR : revised algorithm to account for items crossing 8000 character boundary
--
CREATE PROCEDURE [dbo].[sp_SplitTextList]
@list_text text,
@Delimiter varchar(3)
AS
SET NOCOUNT ON
DECLARE @InputLen integer -- input text length
DECLARE @TextPos integer -- current position within input text
DECLARE @Chunk varchar(8000) -- chunk within input text
DECLARE @ChunkPos integer -- current position within chunk
DECLARE @DelimPos integer -- position of delimiter
DECLARE @ChunkLen integer -- chunk length
DECLARE @DelimLen integer -- delimiter length
DECLARE @ItemBegPos integer -- item starting position in text
DECLARE @ItemOrder integer -- item order in list
DECLARE @DelimChar varchar(1) -- first character of delimiter (simple delimiter)
-- create table to hold list items
-- actually their positions because we may want to scrub this list eliminating bad entries before substring is applied
CREATE TABLE #list_items (item_order integer, item_begpos integer, item_endpos integer)
-- process list
IF @list_text IS NOT NULL
BEGIN
-- initialize
SET @InputLen = DATALENGTH(@list_text)
SET @TextPos = 1
SET @DelimChar = SUBSTRING(@Delimiter, 1, 1)
SET @DelimLen = DATALENGTH(@Delimiter)
SET @ItemBegPos = 1
SET @ItemOrder = 1
SET @ChunkLen = 1
-- cycle through input processing chunks
WHILE @TextPos <= @InputLen AND @ChunkLen <> 0
BEGIN
-- get current chunk
SET @Chunk = SUBSTRING(@list_text, @TextPos, 8000)
-- setup initial variable values
SET @ChunkPos = 1
SET @ChunkLen = DATALENGTH(@Chunk)
SET @DelimPos = CHARINDEX(@DelimChar, @Chunk, @ChunkPos)
-- loop over the chunk, until the last delimiter
WHILE @ChunkPos <= @ChunkLen AND @DelimPos <> 0
BEGIN
-- see if this is a full delimiter
IF SUBSTRING(@list_text, (@TextPos + @DelimPos - 1), @DelimLen) = @Delimiter
BEGIN
-- insert position
INSERT INTO #list_items (item_order, item_begpos, item_endpos)
VALUES (@ItemOrder, @ItemBegPos, (@TextPos + @DelimPos - 1) - 1)
-- adjust positions
SET @ItemOrder = @ItemOrder + 1
SET @ItemBegPos = (@TextPos + @DelimPos - 1) + @DelimLen
SET @ChunkPos = @DelimPos + @DelimLen
END
ELSE
BEGIN
-- adjust positions
SET @ChunkPos = @DelimPos + 1
END
-- find next delimiter
SET @DelimPos = CHARINDEX(@DelimChar, @Chunk, @ChunkPos)
END
-- adjust positions
SET @TextPos = @TextPos + @ChunkLen
END
-- handle last item
IF @ItemBegPos <= @InputLen
BEGIN
-- insert position
INSERT INTO #list_items (item_order, item_begpos, item_endpos)
VALUES (@ItemOrder, @ItemBegPos, @InputLen)
END
-- delete the bad items
DELETE FROM #list_items
WHERE item_endpos < item_begpos
-- return list items
SELECT SUBSTRING(@list_text, item_begpos, (item_endpos - item_begpos + 1)) AS item_text, item_order, item_begpos, item_endpos
FROM #list_items
ORDER BY item_order
END
DROP TABLE #list_items
RETURN
我错过了什么吗?你从哪里得到表格的模式? “sql搜索必须返回所有这些行中的每一行都包含我通过的字符串中的所有单词”。 IN声明不符合OP提出的要求。根据OP表有一个字符串列,用空格隔开单词。该列应该包含通过参数传递的所有单词。 –
@AlexS我对这个答案感觉不好,它来自9年前我写的代码。当我得到时间时,我会解决并添加表变量方法。希望Evan M能够在此期间添加它。 –
除了使用表参数外,还可以将字符串解析为表变量。这就是伪代码会是这样的:
Declare a table variable with one VARCHAR column
While the string is not empty
Grab everything up to the first space and insert it into the table variable
Remove the first word from the string
一旦你有临时表,你可以使用LIKE与你的源表加入它。对于源表中的每一行,连接都会为数组中匹配的每个单词创建一行。然后,您可以使用GROUP/HAVING将其限制为仅针对表变量中每个条目(即与表变量中的每个字符串匹配的那些条目)返回一行的结果。
例如:
DECLARE @TempTable TABLE (Word VARCHAR(100))
...
-- Put logic from the pseudocode above to populate @TempTable from your string
...
SELECT Y.PrimaryKey, MAX(Y.MaybeYouNeedThisColumnToo) from YourTable Y
INNER JOIN @TempTable temp
ON Y.ColumnToMatch LIKE '%' + temp.Word + '%'
GROUP BY Y.PrimaryKey
HAVING COUNT(*) = (SELECT COUNT(*) FROM @TempTable)
您可以使用示例来解释吗? –
如果您可以通过没有伪代码的复制粘贴示例来显示它,这将会很有帮助。 –
表中的单词是如何存储的?这些词是否分类? –
不,这些词没有排序 –
如果您使用的是SQL Server 2008,请尝试使用表值参数http://msdn.microsoft.com/en-us/library/bb510489.aspx –