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

Traduções de Artigos Traduções de Artigos
Artigo: 892406 - Ver produtos para os quais este artigo se aplica.
N.º de bugs: 473209 (SQL Server 8.0)
Expandir tudo | Reduzir tudo

Nesta página

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.

Propriedades

Artigo: 892406 - Última revisão: 2 de novembro de 2007 - Revisão: 2.4
A informação contida neste artigo aplica-se 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
Palavras-chave: 
kbmt kbbug kbtshoot kbprb kbfix KB892406 KbMtpt
Tradução automática
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

Submeter comentários

 

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