REVISIÓN: La configuración para la precisión y la escala de los datos que se devuelve desde un procedimiento almacenado salida parámetro es (38,0) cuando se devuelve un valor null en SQL Server 2000

Seleccione idioma Seleccione idioma
Id. de artículo: 892406 - Ver los productos a los que se aplica este artículo
Nº de error: 473209 (SQL Server 8.0)
Expandir todo | Contraer todo

En esta página

Síntomas

Imagine la situación siguiente: en Microsoft SQL Server 2000, un parámetro de salida del procedimiento almacenado utiliza un tipo de datos decimal o un tipo de datos numéricos. Cuando se devuelve un valor nulo, la configuración para la precisión y la escala de los datos que se devuelve desde el procedimiento almacenado de salida de parámetro es (38,0) . Esta configuración se conserva en posteriores llamadas a procedimiento almacenado. Este comportamiento puede provocar datos se va a redondear un valor entero.

Este problema sólo se aplica a las aplicaciones que utilizan el espacio de nombres System.Data.SqlClient . Este problema no afecta a las aplicaciones que usan otras API de acceso de datos.

Por ejemplo, tener un procedimiento almacenado que tiene un parámetro de salida DECIMAL(19,4) . A continuación, llame al procedimiento almacenado siguiente desde un método SqlCommand.ExecuteNonQuery parametrizado.
CREATE PROCEDURE ParameterPrecisionTest(
	@pIn DECIMAL(19,4), 
	@pOut DECIMAL(19,4) OUTPUT) 
AS
	SET @pOut = @pIn
al hacer esto, experimenta los síntomas siguientes:
  1. Cuando llame al método ExecuteNonQuery y establezca el parámetro de salida SqlParameter en 1.5 , se devuelve 1.5.
  2. Cuando llame al método ExecuteNonQuery y establecer el parámetro de salida SqlParameter en DBNull , se devuelve System.DBNull.
  3. Cuando se llame al método ExecuteNonQuery y establezca el parámetro de salida SqlParameter en 1.5 , se devuelve 2.
Nota En la segunda llamada al procedimiento almacenado, la precisión y la escala se restablecen (38,0) . Se devuelve un valor de 2 en la tercera llamada a procedimiento almacenado.

Causa

Este problema se produce porque SQL Server, se restablece la precisión y la escala en (38,0) cuando se cumplen las condiciones siguientes:
  • Se llama a un procedimiento almacenado que contiene un parámetro de salida SqlParameter .
  • Establezca el parámetro en DBNull .

Solución

Información de Service Pack

Para resolver este problema, consiga el Service Pack más reciente para Microsoft SQL Server 2000. Para obtener más información, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
290211Cómo obtener el Service Pack más reciente de SQL Server 2000

Estado

Este problema se corrigió por primera vez en Pack 4 de Microsoft SQL Server 2000.

Más información

Pasos para reproducir el problema

Ejecute el siguiente código de 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();
		}

	}
}
Nota en este ejemplo, la segunda llamada a procedimiento almacenado establece el parámetro salida en DBNull . Por lo tanto, se restablecen la precisión y la escala (38,0) . El procedimiento almacenado redondea el tercer resultado y, por lo tanto, devuelve un valor de 2.

Propiedades

Id. de artículo: 892406 - Última revisión: viernes, 02 de noviembre de 2007 - Versión: 2.4
La información de este artículo se refiere a:
  • Microsoft SQL Server 2000 Developer Edition
  • Microsoft SQL Server 2000 Standard Edition
  • 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
Palabras clave: 
kbmt kbbug kbtshoot kbprb kbfix KB892406 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 892406

Enviar comentarios

 

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