-1

重複の可能性:
SQL メッセージ 8114、レベル 16、状態 5、プロシージャ sp_product_listing、行 0 データ型 varchar から datetime への変換エラー

これは、私の学校の別の学期の誰かが少し前に尋ねたのを見たことがあります.笑. しかし、彼らが得た答えは、私を本当に満足させるものではありませんでした. 他の質問へのリンクは次のとおりです。SQL Msg 8114、Level 16、State 5、Procedure sp_product_listing、Line 0 Error conversion data type varchar to datetime .

私はSQLに非常に慣れていないので、答えが言うことのほとんどは私にはあまり意味がありません。これについて別の議論を開くことができれば、それは素晴らしいことです. 特に、最近私の質問で行われている教師のバッシングを除いて...

次のステートメントは正常に完了しますが、次のようになります。

CREATE PROCEDURE sp_product_listing
(
     @product varchar(30),
     @month   datetime,
     @year    datetime
)
AS
  SELECT
     'product_name' = products.name,
     products.unit_price,
     products.quantity_in_stock,
     'supplier_name' = suppliers.name
  FROM
     suppliers
  INNER JOIN
     products ON suppliers.supplier_id = products.supplier_id
  INNER JOIN
     order_details ON products.product_id = order_details.product_id
  INNER JOIN
     orders ON order_details.order_id = orders.order_id
  WHERE
     products.name = @product 
     AND MONTH ('orders.order_date') = @month 
     AND YEAR ('orders.order_date') = @year;
GO

プロシージャを実行しようとすると、次のエラー メッセージが表示されます。

メッセージ 8114、レベル 16、状態 5、プロシージャ sp_product_listing、行 0
データ型 varchar を datetime に変換中にエラーが発生しました。

ストアド プロシージャを実行する方法は次のとおりです。

EXECUTE sp_product_listing @product = 'Jack%', @month = 'June', @year = 2001;
GO

datetime2 つのデータ型を varchar に変更しようとしましたが、列自体がdatetime元々データ型であるため、うまくいきませんでした。ここで何が欠けているのかわかりませんか?

アップデート:

これは、 https://stackoverflow.com/users/1554034/valexによって導かれる最終的な解決策でした。

CREATE PROCEDURE sp_product_listing
(
   @product  varchar(30),
   @month    int,
   @year     int
)
AS
   SELECT               
      'product_name' = products.name,
      products.unit_price,
      products.quantity_in_stock,
      'supplier_name' = suppliers.name
   FROM
      suppliers
   INNER JOIN
      products ON suppliers.supplier_id = products.supplier_id
   INNER JOIN 
      order_details ON products.product_id = order_details.product_id
   INNER JOIN 
      orders ON order_details.order_id = orders.order_id
   WHERE
      products.name LIKE @product 
      AND MONTH (orders.order_date) = @month 
      AND YEAR (orders.order_date) = @year;
  GO

また、まだ読んでいる人のために、これが私の先生が私に与えた解決策で、同じ結果が得られます.

CREATE PROCEDURE sp_product_listing
(
@product    varchar(30),
@month      varchar(10),
@year       char(4)
)
AS
    SELECT
       'product_name' = products.name,
       products.unit_price,
       products.quantity_in_stock,
       'supplier_name' = suppliers.name
    FROM
       suppliers
    INNER JOIN
       products ON suppliers.supplier_id = products.supplier_id
    INNER JOIN
       order_details ON products.product_id = order_details.product_id
    INNER JOIN
       orders ON order_details.order_id = orders.order_id
    WHERE   
       products.name LIKE @product 
       AND DATENAME(MONTH,orders.order_date) = @month 
       AND YEAR (orders.order_date) = @year;
   GO
4

2 に答える 2

1

ここには多くの問題があるようです。

orders.order_dateのタイプは。だと思いますdatetime。したがって、関数MONTH (orders.order_date)との結果はYEAR (orders.order_date)整数になります。

これは、行が必要な場合は

MONTH (orders.order_date) = @month AND
YEAR (orders.order_date) = @year;

意味のある動作をするには、パラメータ@month@year実際には整数である必要があります。

これに加えて、where句ではLIKEなく、に対してのみ意味のあるワイルドカードを使用して@productを渡しているように見えます。=

そして最後に'orders.order_date'、関数呼び出しで引用している理由がわかりません-引用は必要ないと思います。

この変更を行うことをお勧めします。

CREATE PROCEDURE    sp_product_listing
(
@product    varchar(30),
@month      int,
@year       int
)
AS
...
WHERE       products.name LIKE @product
...
            MONTH (orders.order_date) = @month AND
            YEAR (orders.order_date) = @year;

次のように呼び出しEXECます。

EXECUTE sp_product_listing @product = 'Jack%', @month = 6, @year = 2001;
GO

上記にもかかわらず、そしてあなたが得ている即時のエラーに関して:

プロシージャ定義では、これらはタイプとして定義されています。つまり、プロシージャを呼び出すときに、SQLエンジンはそれらの値datetimeを受け取ることを期待します。datetime

これに加えて、実行方法では、日付の月と年のコンポーネントのみを表す値をに渡そうとしていますが、SQLエンジンは有効な(つまり完全な)日付を期待していますEXEC@month@year

発生するエラーは、入力値を有効な完全な日付として解釈できないことを示すSQLエンジン'June'です(有効な完全な日付として解釈しようとした場合も同様2001です)。

于 2012-12-10T19:11:18.630 に答える
1

DATEIME「June」が値ではなく、 MONTH関数が を返すため、このエラーが発生しますint。また、@product を MASK として ('%' を使用して) 入力する場合は、LIKE代わりに使用する必要があり=ます。そのため、手順を次のように宣言する必要があります。

CREATE PROCEDURE    sp_product_listing
(
@product    varchar(30),
@month      int,
@year       int
)

....
WHERE               products.name LIKE @product AND
....

そして、それを呼び出します

EXECUTE             sp_product_listing @product = 'Jack%', @month = 6, @year = 2001;
于 2012-12-10T19:13:28.843 に答える