CORRECÇÃO: A definição para a precisão e a escala dos dados que são devolvidos a partir de um procedimento armazenado saída parâmetro é (38,0) quando é devolvido um valor nulo no SQL Server 2000

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática… erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 892406
Este artigo foi arquivado. Este artigo é oferecido "tal como está" e deixará de ser actualizado.
N.º de bugs: 473209 (SQL Server 8.0)
Sintomas
Assumir o seguinte cenário: no Microsoft SQL Server 2000, um parâmetro de saída do procedimento armazenado utiliza um tipo de dados decimal ou de um tipo de dados numéricos. Quando é devolvido um valor nulo, a definição para a precisão e a escala dos dados que são devolvidos a partir do procedimento armazenado saída parâmetro é (38,0) . Esta definição é mantida em chamadas subsequentes para o procedimento armazenado. Este comportamento pode causar dados sejam arredondados para um valor inteiro.

Este problema só se aplica a aplicações que utilizam o espaço de nomes System.data.SqlClient . Este problema não afecta as aplicações que utilizam outro APIs de acesso a dados.

Por exemplo, ter um procedimento armazenado que tem um parâmetro de saída DECIMAL(19,4) . Em seguida, chamar o procedimento armazenado seguinte a partir de um método SqlCommand.ExecuteNonQuery parametrizado.
CREATE PROCEDURE ParameterPrecisionTest(	@pIn DECIMAL(19,4), 	@pOut DECIMAL(19,4) OUTPUT) AS	SET @pOut = @pIn
quando o fizer, detecta os seguintes sintomas:
  1. Quando chamar o método ExecuteNonQuery e definir o parâmetro de saída SqlParameter como 1,5 , 1.5 é devolvido.
  2. Quando chamar o método ExecuteNonQuery e define o parâmetro de saída SqlParameter para DBNull , é devolvido System.DBNull.
  3. Quando chamar o método ExecuteNonQuery e definir o parâmetro de saída SqlParameter como 1,5 , é devolvido 2.
Nota Na segunda chamada para o procedimento armazenado, a precisão e a escala são repostas (38,0) . É devolvido um valor de 2 na terceira chamada para o procedimento armazenado.
Causa
Este problema ocorre porque o SQL Server repõe a precisão e a escala para (38,0) quando se verificam as seguintes condições:
  • Chamar um procedimento armazenado que contém um parâmetro de saída SqlParameter .
  • Defina o parâmetro para DBNull .
Resolução

Informações sobre Service Packs

Para resolver este problema, obtenha o service pack mais recente do Microsoft SQL Server 2000. Para obter mais informações, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
290211Como obter o SQL Server 2000 service pack mais recente
Ponto Da Situação
Este problema foi corrigido pela primeira vez no Microsoft SQL Server 2000 Service Pack 4.
Mais Informação

Passos para reproduzir o problema

Execute o seguinte código do 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();		}	}}
Nota neste exemplo, a segunda chamada para o procedimento armazenado define o parâmetro de saída para DBNull . Por conseguinte, a precisão e a escala são repostas (38,0) . O procedimento armazenado Arredonda o resultado terceiro e assim devolve um valor de 2.

Aviso: Este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 892406 - Última Revisão: 01/17/2015 09:50:28 - Revisão: 2.4

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

  • kbnosurvey kbarchive kbmt kbbug kbtshoot kbprb kbfix KB892406 KbMtpt
Comentários