FIX: 设置精度和小数位数从存储过程返回的数据的输出参数是 (38,0) 时 SQL Server 2000 中,则返回空值

文章翻译 文章翻译
文章编号: 892406 - 查看本文应用于的产品
错误 #: 473209 (SQL Server 8.0)
展开全部 | 关闭全部

本文内容

症状

假定存在以下情况: Microsoft SQL Server 2000,在存储的过程输出参数使用十进制数据类型或数值数据类型。返回一个空值时,精度和从存储过程返回的数据的小数位数设置输出参数是 (38,0)。此设置将会保留该存储过程的后续调用上。此行为可能会导致数据被舍入到整数值。

此问题仅适用于使用 System.Data.SqlClient 命名空间的应用程序。此问题不会影响使用其他数据访问 api 的应用程序。

例如对于必须有一个 DECIMAL(19,4) 输出参数的存储的过程。然后,您将从参数化的 SqlCommand.ExecuteNonQuery 方法调用下列存储的过程。
CREATE PROCEDURE ParameterPrecisionTest(
	@pIn DECIMAL(19,4), 
	@pOut DECIMAL(19,4) OUTPUT) 
AS
	SET @pOut = @pIn
您执行此操作时遇到以下症状:
  1. 当调用 ExecuteNonQuery 方法,并将 SqlParameter 输出参数设置为 1.5 返回 1.5。
  2. 当调用 ExecuteNonQuery 方法,并将 SqlParameter 输出参数设置为 DBNull System.DBNull 返回。
  3. 当调用 ExecuteNonQuery 方法,并将 SqlParameter 输出参数设置为 1.5 返回 2。
注意在存储过程在第二次调用中精度和小数位数将重置为 (38,0)。在第三个调用存储过程返回值为 2。

原因

因为当 SQL Server 精度和小数位数时重置为 (38,0) 满足以下条件为真,就会出现此问题:
  • 调用包含 SqlParameter 输出参数的存储的过程。
  • 将该参数设置为 DBNull

解决方案

服务包信息

若要解决此问题,获得最新的 service pack,对于 Microsoft SQL Server 2000。有关详细的信息请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
290211如何获取最新的 SQL Server 2000 服务包

状态

Microsoft SQL Server 2000 Service Pack 4 中,第一次已得到纠正此问题。

更多信息

重现此问题的步骤

运行下面的 Visual C# 代码。
using System;
using System.Data.SqlClient;
using System.Data;

namespace MyApplication
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	class MyClass
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{
			
			string strConn = "Server=(local);Database=Northwind;" + 
				"Trusted_Connection=Yes;";
			SqlConnection cn = new SqlConnection(strConn);

			// Create stored procedure.
			PrepDb(cn);

			// Simple stored procedure.
			//    Input and output parameters decimal(19, 4).
			//    Sets the output parameter value to the input parameter value.
			SqlCommand cmd = cn.CreateCommand();
			cmd.CommandText = "ParameterPrecisionTest";
			cmd.CommandType = CommandType.StoredProcedure;
			SqlParameter pIn = cmd.Parameters.Add("@pIn", SqlDbType.Decimal);
			pIn.Precision = 19;
			pIn.Scale = 4;
			SqlParameter pOut = cmd.Parameters.Add("@pOut", SqlDbType.Decimal);
			pOut.Precision = 19;
			pOut.Scale = 4;
			pOut.Direction = ParameterDirection.Output;

			cn.Open();

			// Print value, precision, and scale for the output parameter.
			CheckParameter("Pre-execution", pOut);

			// The first call to the procedure returns 1.5.
			pIn.Value = 1.5;
			cmd.ExecuteNonQuery();
			CheckParameter("Returning 1.5", pOut);

			// The second call to the procedure returns null.
			pIn.Value = DBNull.Value;
			cmd.ExecuteNonQuery();
			CheckParameter("Returning DBNull", pOut);

			// The third call to the procedure returns 2.
			pIn.Value = 1.5;
			cmd.ExecuteNonQuery();
			CheckParameter("Returning 1.5", pOut);

			cn.Close();
		}
		static void CheckParameter(string Message, IDbDataParameter Parameter)
		{
			Console.WriteLine("\t{0}", Message);
			Console.WriteLine("\t\tValue:{0}\tPrecision:{1}\tScale:{2}", 
				(Parameter.Value != DBNull.Value) ? Parameter.Value : "DBNull", 
				Parameter.Precision, Parameter.Scale);
			Console.WriteLine();
		}

		static void PrepDb(IDbConnection Connection)
		{
			IDbCommand cmd = Connection.CreateCommand();
			Connection.Open();
			cmd.CommandText = "DROP PROCEDURE ParameterPrecisionTest";
			try {cmd.ExecuteNonQuery();} 
			catch {}
			cmd.CommandText = "CREATE PROCEDURE ParameterPrecisionTest " +
				"(@pIn decimal(19, 4), @pOut decimal(19, 4) OUTPUT) " +
				"AS SET @pOut = @pIn";
			cmd.ExecuteNonQuery();
			Connection.Close();
		}

	}
}
注意 在此示例中,第二次调用该存储过程以 DBNull 设置输出参数。因此,精度和小数位数将重置为 (38,0)。该存储的过程将第三个结果舍入,并因此返回值为 2。

属性

文章编号: 892406 - 最后修改: 2007年11月2日 - 修订: 2.4
这篇文章中的信息适用于:
  • Microsoft SQL Server 2000 Developer Edition
  • Microsoft SQL Server 2000 标准版
  • Microsoft SQL Server 2000 Enterprise Edition
  • Microsoft SQL Server 2000 Personal Edition
  • Microsoft SQL Server 2000 Workgroup Edition
  • Microsoft SQL Server 2000 Desktop Engine (Windows)
  • Microsoft SQL Server 2000 Enterprise Edition 64-bit
关键字:?
kbtshoot kbbug kbfix kbprb kbmt KB892406 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 892406
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com