0

注文内容に関する情報を検索したい。

where @SDateMin as ShipDateMin and @SDateMax as ShipDateMax,

等..

しかし、ストアドプロシージャを実行すると、エラーが発生します:

メッセージ 137、レベル 15、状態 2、行 8
スカラー変数「@spmin」を宣言する必要があります

私のT-SQLコードは次のとおりです。

ALTER PROC sp_SearchOrderDetails
@FName NVARCHAR(30) = NULL,
@LName NVARCHAR(30)= NULL,
@Status BIT = NULL ,
@SDateMin nvarchar(50) = NULL,
@SDateMax nvarchar(50) = NULL,
@ODateMin nvarchar(50) = NULL,
@ODateMax nvarchar(50) = NULL
AS
BEGIN
 DECLARE @SqlStr NVARCHAR(MAX), 
         @ParamList NVARCHAR(2000)
 SELECT @SqlStr = 'SELECT O.* FROM dbo.OrderDetails O where (1=1)'
 IF @FName IS NOT NULL
    SELECT @SqlStr = @SqlStr + 'AND ( O.FirstName like''%' + @FName + '%'')'
 IF @LName IS NOT NULL
    SELECT @SqlStr = @SqlStr + 'AND ( O.LastName like''%' + @LName + '%'')'
If @SDateMin IS NOT NULL  AND @SDateMax IS NOT NULL
        DECLARE @spmin DATE =  Convert(DATE,@SDateMin,105)
        DECLARE @spmax DATE =  Convert(DATE,@SDateMax,105)
        SELECT @SqlStr = @SqlStr + 'AND ( O.ShipDate BETWEEN @spmin AND @spmax )'   
If @ODateMin IS NOT NULL AND @ODateMax IS NOT NULL
        DECLARE @odmin DATE =  Convert(DATE,@ODateMin,105)
        DECLARE @odmax DATE =  Convert(DATE,@ODateMax,105)
        SELECT @SqlStr = @SqlStr + 'AND ( O.OrderDate BETWEEN @odmin AND  @odmax )'
If @Status IS NOT NULL
    SELECT @SqlStr = @SqlStr + 'AND ( O.ShipStatus = @Status )'
SELECT @ParamList = '
        @FName nvarchar(30),
        @LName nvarchar(30),
        @Status bit,
        @SDateMin nvarchar(50),
        @SDateMax nvarchar(50),
        @ODateMin nvarchar(50),
        @ODateMax nvarchar(50)'
EXEC SP_EXECUTESQL  @SqlStr,
                    @ParamList,
                    @FName,
                    @LName ,
                    @Status,
                    @SDateMin,
                    @SDateMax,
                    @ODateMin,
                    @ODateMax
END

実行:

   DECLARE  @return_value int

EXEC    @return_value = [dbo].[sp_SearchOrderDetails]
        @SDateMin = N'10-10-2011',
        @SDateMax = N'10-10-2012'

SELECT  'Return Value' = @return_value

GO




CREATE TABLE [dbo].[OrderDetails](
    [OrderDetailId] [int] IDENTITY(1,1) NOT NULL,
    [CustomerTitle] [nvarchar](5) NOT NULL,
    [FirstName] [nvarchar](18) NOT NULL,
    [LastName] [nvarchar](22) NOT NULL,
    [PhoneNumber] [nvarchar](15) NOT NULL,
    [Email] [nvarchar](30) NOT NULL,
    [Address] [nvarchar](60) NOT NULL,
    [Country] [nvarchar](20) NOT NULL,
    [ShipStatus] [bit] NOT NULL,
    [OrderDate] [datetime] NOT NULL,
    [ShipDate] [datetime] NOT NULL,
    [PaymentProvider] [nvarchar](20) NOT NULL,
    [Deliver] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_OrderDetails] PRIMARY KEY CLUSTERED 
(
    [OrderDetailId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
4

1 に答える 1

0

@ParamList には、プロシージャ宣言で名前が付けられたとおりのパラメーターが含まれていますが、後で同様の名前の別の変数を導入します。converts は実際には日付であることを示唆しているため、データ型も変更しました。

SELECT @ParamList = '
        @FName nvarchar(30),
        @LName nvarchar(30),
        @Status bit,
        @spmin date,
        @spmax date,
        @odmin date,
        @odmax date'

編集:最後のコメントがわかりません。begin ... end問題を解決するには、IF の後にコードをブロックで囲む必要があります。

ALTER PROC sp_SearchOrderDetails
@FName NVARCHAR(30) = NULL,
@LName NVARCHAR(30)= NULL,
@Status BIT = NULL ,
@SDateMin nvarchar(50) = NULL,
@SDateMax nvarchar(50) = NULL,
@ODateMin nvarchar(50) = NULL,
@ODateMax nvarchar(50) = NULL
AS
BEGIN
 DECLARE @SqlStr NVARCHAR(MAX), 
         @ParamList NVARCHAR(2000)
 SELECT @SqlStr = 'SELECT O.* FROM dbo.OrderDetails O where (1=1)'
 IF @FName IS NOT NULL
    SELECT @SqlStr = @SqlStr + 'AND ( O.FirstName like''%' + @FName + '%'')'
 IF @LName IS NOT NULL
    SELECT @SqlStr = @SqlStr + 'AND ( O.LastName like''%' + @LName + '%'')'
If @SDateMin IS NOT NULL  AND @SDateMax IS NOT NULL
BEGIN
        DECLARE @spmin DATE =  Convert(DATE,@SDateMin,105)
        DECLARE @spmax DATE =  Convert(DATE,@SDateMax,105)
        SELECT @SqlStr = @SqlStr + 'AND ( O.ShipDate BETWEEN @spmin AND @spmax )'   
END
If @ODateMin IS NOT NULL AND @ODateMax IS NOT NULL
BEGIN
        DECLARE @odmin DATE =  Convert(DATE,@ODateMin,105)
        DECLARE @odmax DATE =  Convert(DATE,@ODateMax,105)
        SELECT @SqlStr = @SqlStr + 'AND ( O.OrderDate BETWEEN @odmin AND  @odmax )'
END
If @Status IS NOT NULL
    SELECT @SqlStr = @SqlStr + 'AND ( O.ShipStatus = @Status )'
SELECT @ParamList = '
        @FName nvarchar(30),
        @LName nvarchar(30),
        @Status bit,
        @spmin date,
        @spmax date,
        @odmin date,
        @odmax date'

EXEC SP_EXECUTESQL  @SqlStr,
                    @ParamList,
                    @FName,
                    @LName ,
                    @Status,
                    @spmin,
                    @spmax,
                    @odmin,
                    @odmax
END

if の後に 1 行しかない場合でも、これを行うことをお勧めします。これは、いつそれを拡張する必要があるのか​​ わからないためです。また、その時点で新しいコードの開始と終了を忘れがちです。校正ではなく、他の何かを解決しています。

于 2012-07-25T10:24:15.780 に答える