我正在尝试从ASP脚本将其转换为SQL Server中的存储过程。我试图遵循http://www.sommarskog.se/dyn-search.html中概述的程序,但由于缺乏理解;我无法弄清楚创建搜索字符串需要什么。一旦我能弄明白,那么我可以将字符串附加到动态sql的其余部分。我有list函数列表,以及数据库中定义的intList_tabletype,以及SP的其余部分。 searchArr变量可以是一个关键字,关键字或短语的分隔列表。任何帮助将不胜感激。感谢
'SQL - Keywords
If Len(strSearch) > 0 Then
'Create array of keywords. If we're doing a PHRase
'search, an array with only one position is created
'containing the entire search string. If an AND or
'an OR "keyword" search is being performed, each word
'is put into it's own array position.
If strSearchType = "PHR" Then
searchArr(0) = Trim(strSearch)
Else
searchArr = strSearch.Split(" "c)
End If
'Keyword search SQL
tmpSQL1 = "(Brewery.BreweryName LIKE "
tmpSQL2 = "(Products.description LIKE "
tmpSQL3 = "(Products.Notes LIKE "
tmpSQL4 = "(Products.SKU LIKE "
For i = 0 To UBound(searchArr)
If i = UBound(searchArr) Then
tmpSQL1 = tmpSQL1 & "'%" & searchArr(i) & "%')"
tmpSQL2 = tmpSQL2 & "'%" & searchArr(i) & "%')"
tmpSQL3 = tmpSQL3 & "'%" & searchArr(i) & "%')"
tmpSQL4 = tmpSQL4 & "'%" & searchArr(i) & "%')"
Else
tmpSQL1 = tmpSQL1 & "'%" & searchArr(i) & "%' " & strSearchType & " Brewery.BreweryName LIKE "
tmpSQL2 = tmpSQL2 & "'%" & searchArr(i) & "%' " & strSearchType & " Products.description LIKE "
tmpSQL3 = tmpSQL3 & "'%" & searchArr(i) & "%' " & strSearchType & " Products.Notes LIKE "
tmpSQL4 = tmpSQL4 & "'%" & searchArr(i) & "%' " & strSearchType & " Products.SKU LIKE "
End If
Next
'Put it all together
searchSQL = searchSQL & "AND (" & tmpSQL1 & " OR " & tmpSQL2 & " OR " & tmpSQL3 & " OR " & tmpSQL4 & ") "
End If
当我在网页上运行此脚本时,我会收到此字符串。
单个关键字或短语
AND ((Brewery.BreweryName LIKE '%Bud%') OR (Products.description LIKE '%Bud%') OR (Products.Notes LIKE '%Bud%') OR (Products.SKU LIKE '%Bud%') OR (Brands.Brand LIKE '%Bud%'))
多个关键字
AND ((Brewery.BreweryName LIKE '%Bud%' OR Brewery.BreweryName LIKE '%Busch%') OR (Products.description LIKE '%Bud%' OR Products.description LIKE '%Busch%') OR (Products.Notes LIKE '%Bud%' OR Products.Notes LIKE '%Busch%') OR (Products.SKU LIKE '%Bud%' OR Products.SKU LIKE '%Busch%') OR (Brands.Brand LIKE '%Bud%' OR Brands.Brand LIKE '%Busch%'))
这是我到目前为止所提出的程序。
ALTER PROCEDURE [dbo].[GetProductsBySearch]
@idProduct int = NULL,
@sku nvarchar(20) = NULL,
@breweryname nvarchar(40) = NULL,
@brand nvarchar(40) = NULL,
@country nvarchar(15) = NULL,
@prodname nvarchar(40) = NULL,
@searchStr nvarchar(MAX) = NULL,
--@PHRtbl intlist_tbltype READONLY,
@sortExpression nvarchar(50) = NULL,
@startRowIndex int,
@maximumRows int,
@idLocation int = NULL,
@idBrand int = NULL,
@strSearchType nvarchar(5) = ' OR ',
@debug bit = 0
AS
DECLARE @sql nvarchar(MAX),
@paramlist nvarchar(4000),
@nl char(2) = char(13) + char(10)
DECLARE @PHRtbl TABLE
( PK INT IDENTITY(1,1) PRIMARY KEY,
item NVARCHAR (MAX)
)
IF @sortExpression IS NULL
SET @sortExpression = 'sku'
INSERT INTO @PHRtbl
SELECT item FROM [dbo].[udf_List2Table](@searchStr,',')
DECLARE @i INT
SELECT @i = MIN(PK) FROM @PHRtbl
DECLARE @max INT
SELECT @max = MAX(PK) FROM @PHRtbl
DECLARE @SearchSQL AS NVARCHAR(MAX) = ''
DECLARE @item AS NVARCHAR(MAX) = NULL
DECLARE @tmpSQL1 AS NVARCHAR(MAX) = '(Brewery.BreweryName LIKE '
DECLARE @tmpSQL2 AS NVARCHAR(MAX) = '(Products.description LIKE '
DECLARE @tmpSQL3 AS NVARCHAR(MAX) = '(Products.Notes LIKE '
DECLARE @tmpSQL4 AS NVARCHAR(MAX) = '(Products.SKU LIKE '
DECLARE @tmpSQL5 AS NVARCHAR(MAX) = '(Brands.Brand LIKE '
SELECT @sql =
'SELECT SKU, productName, imgUrlThumb, Size, ProdType, CanType,
CanManufacturer, breweryName, locName, CountryFlag, Brand
FROM
(SELECT Products.SKU, Products.Description as productName, Products.imgUrlThumb, LookupSize.Size, ProdType.ProdType, CanTypes.Description AS CanType,
CanManufacturer.CanManufacturer, brewery.breweryName, Locations.locName, Locations.CountryFlag, Brands.Brand,
ROW_NUMBER() OVER(ORDER BY ' + @sortExpression + ') AS RowNum
FROM Products INNER JOIN
brewery ON Products.idBrewery = brewery.idBrewery INNER JOIN
CanManufacturer ON Products.idCanManufacturer = CanManufacturer.idCanManufacturer INNER JOIN
CanTypes ON Products.idCanType = CanTypes.idCanType INNER JOIN
Locations ON brewery.idLocation = Locations.idLocation INNER JOIN
LookupSize ON Products.idSize = LookupSize.idSize INNER JOIN
ProdType ON Products.idProdType = ProdType.idProdtype INNER JOIN
CatProd ON Products.idProduct = CatProd.idProduct INNER JOIN
Categories ON CatProd.idCategory = Categories.idCategory INNER JOIN
Brands ON Brands.idBrand = Products.idBrand
WHERE 1 = 1 ' + @nl
IF @searchStr IS NOT NULL
WHILE @i <= @max
BEGIN
SELECT @item = item FROM @PHRtbl WHERE PK = @i
IF (@i = @max)
BEGIN
SET @tmpSQL1 += ''%'' & @item + ''%')'
SET @tmpSQL2 += ''%'' & @item + ''%')'
SET @tmpSQL3 += ''%'' & @item + ''%')'
SET @tmpSQL4 += ''%'' & @item + ''%')'
SET @tmpSQL5 += ''%'' & @item + ''%')'
END
ELSE
BEGIN
SET @tmpSQL1 += ''%'' & @item + ''%')' + @strSearchType + ' Brewery.BreweryName LIKE '
SET @tmpSQL2 += ''%'' & @item + ''%')' + @strSearchType + ' Products.description LIKE '
SET @tmpSQL3 += ''%'' & @item + ''%')' + @strSearchType + ' Products.Notes LIKE '
SET @tmpSQL4 += ''%'' & @item + ''%')' + @strSearchType + ' Products.SKU LIKE '
SET @tmpSQL5 += ''%'' & @item + ''%')' + @strSearchType + ' Brands.Brand LIKE '
END
SELECT @item = NULL
SET @i = @i + 1
END
--moved this out of the while loop
-- put it all together
SET @SearchSQL = @SearchSQL + 'AND (' + @tmpSQL1 + ' OR ' + @tmpSQL2 + ' OR ' + @tmpSQL3 + ' OR ' + @tmpSQL4 + ' OR ' + @tmpSQL5 + ') ' + @nl
-- Uncommend below to check the SQL
PRINT @SearchSQL
SELECT @sql += ' @SearchSQL' + @nl
IF @idProduct IS NOT NULL
SELECT @sql += ' AND Products.idProduct = @idProduct' + @nl
IF @idBrand IS NOT NULL
SELECT @sql += ' AND Products.idBrand = @idBrand' + @nl
IF @idLocation IS NOT NULL
SELECT @sql += ' AND Brewery.idLocation = @idLocation' + @nl
IF @brand IS NOT NULL
SELECT @sql += ' AND Brands.brand LIKE ''%'' + @brand + ''%''' + @nl
IF @breweryname IS NOT NULL
SELECT @sql += ' AND Brewery.breweryName LIKE ''%'' + @breweryname + ''%''' + @nl
IF @prodname IS NOT NULL
SELECT @sql += ' AND Products.Description LIKE ''%'' + @prodname + ''%''' + @nl
IF @searchStr IS NOT NULL
SELECT @sql += ' @searchStr' + @nl
SELECT @sql += ') AS myData
WHERE RowNum BETWEEN (' + CONVERT(nvarchar(10), @startRowIndex) +
' - 1) * ' + CONVERT(nvarchar(10),@MaximumRows) + ' AND (((' + CONVERT(nvarchar(10), @startRowIndex) + ' - 1) * '
+ CONVERT(nvarchar(10), @maximumRows) + ' + 1) + ' + CONVERT(nvarchar(10), @maximumRows) + ') - 1'
--IF EXISTS (SELECT * FROM @PHRtbl)
-- SELECT @sql += ' AND o.EmployeeID IN (SELECT val FROM @employeetbl)' + @nl
--SELECT @sql += ' ORDER BY o.OrderID' + @nl
IF @debug = 1
PRINT @sql
SELECT @paramlist = '@idProduct int,
@sku nvarchar(20) ,
@breweryname nvarchar(40) ,
@brand nvarchar(40) ,
@country nvarchar(15) ,
@prodname nvarchar(40) ,
@searchStr nvarchar(MAX) ,
@PHRtbl intlist_tbltype READONLY,
@sortExpression nvarchar(50),
@startRowIndex int,
@maximumRows int,
@idLocation int,
@idBrand int,
@strSearchType nvarchar(5)'
EXEC sp_executesql @sql, @paramlist,
@idProduct,@sku,@breweryname,@brand,@country,@prodname,@searchStr,@PHRtbl,@sortExpression,
@startRowIndex,@maximumRows,@idLocation,@idBrand
现在,当我尝试执行该过程时,我收到以下错误。由于While循环构建字符串。知道我必须找出导致错误的原因,然后构建字符串并附加正在构建的@SQL。
**消息402,级别16,状态1,过程GetProductsBySearch,第75行 数模类型varchar和varchar在模运算符中不兼容。 **
我能够通过更改此部分中的引号来获取在数据库中编译的过程。
IF (@i = @max)
BEGIN
SET @tmpSQL1 += '''%' + @item + '%'')'
SET @tmpSQL2 += '''%' + @item + '%'')'
SET @tmpSQL3 += '''%' + @item + '%'')'
SET @tmpSQL4 += '''%' + @item + '%'')'
SET @tmpSQL5 += '''%' + @item + '%'')'
END
ELSE
BEGIN
SET @tmpSQL1 += '''%' + @item + '%'')' + @strSearchType + ' Brewery.BreweryName LIKE '
SET @tmpSQL2 += '''%' + @item + '%'')' + @strSearchType + ' Products.description LIKE '
SET @tmpSQL3 += '''%' + @item + '%'')' + @strSearchType + ' Products.Notes LIKE '
SET @tmpSQL4 += '''%' + @item + '%'')' + @strSearchType + ' Products.SKU LIKE '
SET @tmpSQL5 += '''%' + @item + '%'')' + @strSearchType + ' Brands.Brand LIKE '
END
现在,当我执行它时,我收到此错误。 Msg 206,Level 16,State 2,Line 0 操作数类型冲突:表与nvarchar
不兼容我怀疑上面的部分是罪魁祸首。我有一个打印声明来打印字符串,因为它们已经构建,错误首先出现。我在哪里或如何看到@SearchStr变量的样子?
我已将该部分代码提取到一个新窗口中。使用searchStr变量中的一个值,我得到了searchSQL的正确构建。
AND ((Brewery.BreweryName LIKE '%Bud%')
OR (Products.description LIKE '%Bud%')
OR (Products.Notes LIKE '%Bud%')
OR (Products.SKU LIKE '%Bud%')
OR (Brands.Brand LIKE '%Bud%')
)
然而,当我在列表中添加另一个项目时,我得到了这个:
AND ((Brewery.BreweryName LIKE '%Bud%') OR Brewery.BreweryName LIKE
OR (Products.description LIKE '%Bud%') OR Products.description LIKE
OR (Products.Notes LIKE '%Bud%') OR Products.Notes LIKE
OR (Products.SKU LIKE '%Bud%') OR Products.SKU LIKE
OR (Brands.Brand LIKE '%Bud%') OR Brands.Brand LIKE
)
我快到了。只需要确定字符串的哪个部分需要重新调整才能正确
AND ((Brewery.BreweryName LIKE '%Bud%') OR Brewery.BreweryName LIKE
'%Busch%')
OR (Products.description LIKE '%Bud%') OR Products.description LIKE
'%Busch%')
OR (Products.Notes LIKE '%Bud%') OR Products.Notes LIKE
'%Busch%')
OR (Products.SKU LIKE '%Bud%') OR Products.SKU LIKE
'%Busch%')
OR (Brands.Brand LIKE '%Bud%') OR Brands.Brand LIKE
'%Busch%')
)