问题选择2号查询?

时间:2010-07-23 01:40:47

标签: sql sql-server tsql stored-procedures

我只是在选择palletnumber = datatype is int时创建了这个存储过程。 SerialNumber是varchar。 然后托盘编号为1 - 200 ..但如果我输入2则显示2与其他托盘编号。 我将@search更改为nchar,但是ok,但是serialnumber有错误。 我是存储过程的新手。

ALTER PROCEDURE [dbo].[sp_SearchFresh]
    -- Add the parameters for the stored procedure here
    @Search varchar(50)--so that i only have one search engine/input box
AS
SELECt  dbo.Monitor.SerialNumber, 
      WIP.dbo.WIPTEST.PartNumber,
      dbo.Monitor.PalletNumber
FROM  WIP.dbo.WIPTEST 
      INNER JOIN dbo.Monitor 
         ON WIP.dbo.WIPTEST.SerialNumber = dbo.Monitor.SerialNumber
WHERE WIP.dbo.WIPTEST.StatusDescription = 'FG-FRESH' 
    AND (dbo.Monitor.PalletNumber = @Search 
        OR dbo.Monitor.SerialNumber LIKE @Search + '%' )
END

它的工作原理..我将练习动态SQL。但是我如何在我的ui上提供空值? 这是我的DAL代码

public DataSet FGSearch_Grid(Ientity用户)         {

        SqlConnection conn = new SqlConnection(connStr);
        SqlCommand cmd = new SqlCommand("sp_SearchFresh", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        DataSet dSet = new DataSet();
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        cmd.Parameters.Add("@Search", SqlDbType.VarChar, 50).Value = user.Search;

        try
        {
            conn.Open();

            da.Fill(dSet, "WIPDATA");

            conn.Close();
        }
        catch (SqlException)
        {
            throw;
        }
        return dSet;
    }

4 个答案:

答案 0 :(得分:2)

您很快发现使用单个参数不能很好地提供具有不同数据类型的多个过滤条件。让自己更容易,并接受对于您想要提供的每个单独的过滤条件,必须有一个单独的存储过程参数参数。

ALTER PROCEDURE [dbo].[sp_SearchFresh]    
  @Searchvarchar(50),
  @pallet_num INT

AS

  SELECT dbo.Monitor.SerialNumber,      
              WIP.dbo.WIPTEST.PartNumber,      
              dbo.Monitor.PalletNumber
    FROM  WIP.dbo.WIPTEST       
      JOIN dbo.Monitor ON WIP.dbo.WIPTEST.SerialNumber = dbo.Monitor.SerialNumber
  WHERE WIP.dbo.WIPTEST.StatusDescription = 'FG-FRESH'   
     AND (@pallet_num IS NULL OR dbo.Monitor.PalletNumber = @pallet_num)
     AND (@Search IS NULL OR dbo.Monitor.SerialNumber LIKE @Search+'%')

END

答案 1 :(得分:1)

让@Search和palletnumber评估为int try

AND (dbo.Monitor.PalletNumber = cast(@Search as int)

答案 2 :(得分:0)

确保您获得的托盘编号没有以2开头的序列号?

答案 3 :(得分:0)

小心使用“Catch All Queries”,因为它们总是会导致全表扫描。如果您不了解它们,请查看Gail Shawn的博客Catch All Queries

确保使用可选参数进行索引利用的唯一方法是动态SQL(确保使用sp_executesql来避免SQL注入):

ALTER PROCEDURE [dbo].[sp_SearchFresh]    
  @search varchar(50),
  @pallet_num INT
AS

DECLARE @sql NVARCHAR(4000);

SET @sql = N'
  SELECT dbo.Monitor.SerialNumber,      
              WIP.dbo.WIPTEST.PartNumber,      
              dbo.Monitor.PalletNumber
    FROM  WIP.dbo.WIPTEST       
      JOIN dbo.Monitor ON WIP.dbo.WIPTEST.SerialNumber = dbo.Monitor.SerialNumber
  WHERE WIP.dbo.WIPTEST.StatusDescription = ''FG-FRESH'''

IF (@search IS NOT NULL)
BEGIN
   SET @sql = @sql + ' AND dbo.Monitor.SerialNumber LIKE @searchIN';
   SET @search = REPLACE(@search, '%', '%%') + '%';
END

IF (@pallet_num IS NOT NULL)
   SET @sql = @sql + ' AND dbo.Monitor.PalletNumber = @pallet_numIN';

EXECUTE sp_executesql 
            @sql
            ,N'@searchIN VARCHAR(50), @pallet_numIN INT'
            ,@searchIN = @search
            ,@pallet_numIN = @pallet_num;