【问题标题】:Sql Exception : Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this querySql 异常:不允许从数据类型 datetime 到 int 的隐式转换。使用 CONVERT 函数运行此查询
【发布时间】:2014-01-27 14:56:46
【问题描述】:

这是我的存储过程:

ALTER PROCEDURE [dbo].[NextPrevPost]
@PostQueryString NVARCHAR(100),
@NextID INT OUTPUT,
@NextTitle NVARCHAR(500) OUTPUT,
@NextPostDate DATETIME OUTPUT,
@NextQueryString NVARCHAR(100) OUTPUT,
@PrevID INT OUTPUT,
@PrevTitle NVARCHAR(500) OUTPUT,
@PrevPostDate DATETIME OUTPUT,
@PrevQueryString NVARCHAR(100) OUTPUT
AS
BEGIN
    DECLARE @ID INT;
    SELECT @ID=PostID FROM Post WHERE PostQueryString=@PostQueryString;

   SELECT TOP 1 
      @NextID = COALESCE(P.PostID,0),
      @NextTitle = P.PostTitle,
      @NextPostDate = COALESCE(P.PostDate, getdate()),
      @NextQueryString = P.PostQueryString 
   FROM 
      Post P 
   WHERE 
      P.PostDate >= (SELECT PostDate FROM Post WHERE PostID = @ID) 
      AND P.PostID != @ID
   ORDER BY 
      PostDate ASC

   SELECT TOP 1 
      @PrevID = COALESCE(P.PostID, 0),
      @PrevTitle = P.PostTitle,
      @PrevPostDate = COALESCE(P.PostDate, GETDATE()),
      @PrevQueryString = P.PostQueryString
   FROM 
      Post P 
   WHERE 
      P.PostDate <= (SELECT PostDate FROM Post WHERE PostID = @ID) 
      AND P.PostID != @ID
   ORDER BY 
      PostDate DESC

   IF(@PrevPostDate IS NULL)
   BEGIN
        SET @PrevPostDate = GETDATE();
   END

   IF(@NextPostDate IS NULL)
   BEGIN
        SET @NextPostDate = GETDATE();
   END

SET @PrevPostDate=GETDATE();
SET @NextPostDate=GETDATE();

这是我调用之前存储过程的 c# 函数:

private void SetNextPrev(string s)
{
    SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BlogConnectionString"].ConnectionString);

    SqlCommand command = new SqlCommand("NextPrevPost",connection);
    connection.Open();

    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.Add(new SqlParameter("PostQueryString", DbType.String)).Value = s;

    SqlParameter nextid = new SqlParameter("NextID", DbType.Int32);
    nextid.Direction = ParameterDirection.Output;
    command.Parameters.Add(nextid);

    SqlParameter nexttitle = new SqlParameter("NextTitle", DbType.String);
    nexttitle.Direction = ParameterDirection.Output;
    command.Parameters.Add(nexttitle);

    SqlParameter NextPostDate = new SqlParameter("NextPostDate", DbType.DateTime);
    NextPostDate.Direction = ParameterDirection.Output;
    command.Parameters.Add(NextPostDate);

    SqlParameter NextQueryString = new SqlParameter("NextQueryString", DbType.String);
    NextQueryString.Direction = ParameterDirection.Output;
    command.Parameters.Add(NextQueryString);

    SqlParameter prevtid = new SqlParameter("PrevID", DbType.Int32);
    prevtid.Direction = ParameterDirection.Output;
    command.Parameters.Add(prevtid);

    SqlParameter prevtitle = new SqlParameter("PrevTitle", DbType.String);
    prevtitle.Direction = ParameterDirection.Output;
    command.Parameters.Add(prevtitle);

    SqlParameter PrevPostDate = new SqlParameter("PrevPostDate", DbType.DateTime);
    PrevPostDate.Direction = ParameterDirection.Output;
    command.Parameters.Add(PrevPostDate);

    SqlParameter PrevQueryString = new SqlParameter("PrevQueryString", DbType.String);
    PrevQueryString.Direction = ParameterDirection.Output;
    command.Parameters.Add(PrevQueryString);

    try
    {
        command.ExecuteNonQuery();

        if (prevtid.Value.ToString()!=string.Empty)
        {
        }

        if (nextid.Value.ToString()!=string.Empty)
        {
        }
    }
    catch { }
    finally { command.Dispose(); connection.Close(); }
}

我得到了错误:

不允许从数据类型 datetime 到 int 的隐式转换。使用 CONVERT 函数运行此查询。

为什么?

谢谢!

更新!

@BoStigChristensen 我从 DbType 更改为 SqlDbType 类型。所以我的 c# 函数看起来像这样:

   private void SetNextPrev(string s)
{

    SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BlogConnectionString"].ConnectionString);
    SqlCommand command = new SqlCommand("NextPrevPost",connection);
    connection.Open();

    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.Add(new SqlParameter("PostQueryString", SqlDbType.NVarChar)).Value = s;


    SqlParameter nextid = new SqlParameter("NextID", SqlDbType.Int);
    nextid.Direction = ParameterDirection.Output;
    command.Parameters.Add(nextid);

    SqlParameter nexttitle = new SqlParameter("NextTitle", SqlDbType.NVarChar);
    nexttitle.Direction = ParameterDirection.Output;
    command.Parameters.Add(nexttitle);

    SqlParameter NextPostDate = new SqlParameter("NextPostDate", SqlDbType.DateTime);
    NextPostDate.Direction = ParameterDirection.Output;
    command.Parameters.Add(NextPostDate);


    SqlParameter NextQueryString = new SqlParameter("NextQueryString", SqlDbType.NVarChar);
    NextQueryString.Direction = ParameterDirection.Output;
    command.Parameters.Add(NextQueryString);

    SqlParameter prevtid = new SqlParameter("PrevID", SqlDbType.Int);
    prevtid.Direction = ParameterDirection.Output;
    command.Parameters.Add(prevtid);


    SqlParameter prevtitle = new SqlParameter("PrevTitle", SqlDbType.NVarChar);
    prevtitle.Direction = ParameterDirection.Output;
    command.Parameters.Add(prevtitle);


    SqlParameter PrevPostDate = new SqlParameter("PrevPostDate", SqlDbType.DateTime);
    PrevPostDate.Direction = ParameterDirection.Output;
    command.Parameters.Add(PrevPostDate);


    SqlParameter PrevQueryString = new SqlParameter("PrevQueryString", SqlDbType.NVarChar);
    PrevQueryString.Direction = ParameterDirection.Output;
    command.Parameters.Add(PrevQueryString);

    try
    {
        command.ExecuteNonQuery();

        if (prevtid.Value.ToString()!=string.Empty)
        {

        }

        if (nextid.Value.ToString()!=string.Empty)
        {

        }
    }
    catch { }
    finally { command.Dispose(); connection.Close(); }

}

但不幸的是它抛出了错误: String[2]:Size 属性的大小为 0 无效。

【问题讨论】:

  • 如果您手动(通过 SSMS)执行此 SP 是否会出现相同的错误?
  • 我没有看到您为任何参数赋值。你在某个地方这样做吗?问题出在NextPostDate。我看到你用类型和方向设置了参数,但没有值。
  • @Evan 除了第一个参数PostQueryString,它们都是输出。
  • @MarkoJuvančič 不,如果我通过 SSMS 执行存储过程,我不会收到任何错误。
  • @Otix - 最后一个错误是因为您必须像这样设置SqlDbType.NVarChar 参数的长度:outParam.Size = 50; Bo 的答案加上这应该可以继续。

标签: sql sql-server datetime stored-procedures parameters


【解决方案1】:

SqlParameter 构造函数采用SqlDbType 而不是DbType

SqlParameter(String, SqlDbType)

传递正确的类型SqlDbType :-)

通过将DbType.DateTime 传递给SqlDbType 参数,您基本上是在传递一个可能错误的映射,从而导致不可预测的结果。

一个例子:

using System;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            const SqlDbType MY_SQL_ENUM = new SqlDbType();
            const DbType MY_DB_ENUM = new DbType();

            var wrongParam = new SqlParameter("WrongTest", DbType.DateTime);
            Console.WriteLine(Enum.GetName(MY_DB_ENUM.GetType(), wrongParam.DbType));
            Console.WriteLine(Enum.GetName(MY_SQL_ENUM.GetType(), wrongParam.SqlDbType));

            var rightParam = new SqlParameter("RightTest", SqlDbType.DateTime);
            Console.WriteLine(Enum.GetName(MY_DB_ENUM.GetType(), rightParam.DbType));
            Console.WriteLine(Enum.GetName(MY_SQL_ENUM.GetType(), rightParam.SqlDbType));

            Console.ReadKey();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多