2009-02-22 9 views
5

Le he preguntado a algunas personas por qué el uso de xml como parámetro en el procedimiento almacenado no funciona y todos dijeron que así es. No puedo creer eso.C#/SQL - ¿Qué pasa con SqlDbType.Xml en los procedimientos?

command.Parameters.Add("@xmldoc", SqlDbType.Xml); 

Ahí es donde compilador devuelve el error y no puedo usar Nvarchar beacouse se limiteed a 4k canta. XML sería perfecto, ya que puede ser 2 piezas grandes.

¿Por qué otros SqlDbTypes funcionan bien y este restituye el error?

*

Error: Specified argument was out of the range of valid values. Parameter name: @xmldoc: Invalid SqlDbType enumeration value: 25.

*

+0

podría ser bueno adjuntar el error si alguno a la publicación. –

+0

Supongo que está utilizando al menos SQL2005 y que su columna está declarada como un tipo de datos XML. – GregD

+0

si usa SQL Server 2005 en adelante, existe un límite mayor para el tamaño de las cadenas NVARCHAR. Consulte la palabra clave MAX - http://msdn.microsoft.com/en-us/library/ms186939.aspx - MAX indica que la longitud máxima para NVARCHAR es 1.073.741.822 –

Respuesta

13

Funciona. Tendrá que configurar el valor como SqlXml y no como una cadena, pero se puede hacer. Imagínese esta tabla:

CREATE TABLE XmlTest 
(
    [XmlTestId] [int] identity(1,1) primary key, 
    [XmlText] [xml] NOT NULL 
) 

Y el sproc:

CREATE PROCEDURE XmlTest_Insert 
(
    @XmlText xml 
) 
AS 

INSERT INTO XmlTest (XmlText) 
VALUES (@XmlText) 

Ahora represente una aplicación de consola que tiene este aspecto:

using System.Data.SqlClient; 
using System.Data; 
using System.Data.SqlTypes; 
using System.Xml; 

namespace TestConsole 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 
      string xmlDoc = "<root><el1>Nothing</el1></root>"; 
      string connString = "server=(local);database=IntroDB;UID=sa;PWD=pwd"; 
      SqlConnection conn = new SqlConnection(connString); 
      SqlCommand cmd = new SqlCommand("XmlTest_Insert", conn); 
      cmd.CommandType = CommandType.StoredProcedure; 
      SqlParameter param = new SqlParameter("@XmlText", SqlDbType.Xml); 
      param.Value = new SqlXml(new XmlTextReader(xmlDoc 
          , XmlNodeType.Document, null)); 
      cmd.Parameters.Add(param); 

      conn.Open(); 
      cmd.ExecuteNonQuery(); 
      conn.Dispose(); 
     } 
    } 
} 

Bingo!

Esto se hizo en Visual Studio 2008 (.NET 3.5), pero estoy bastante seguro de que debería funcionar también en Visual Studio 2005 (2.0 Framework).

+0

Su ejemplo funciona perfectamente como debería, aunque cuando lo pruebo en mi aplicación CF 3.5 sigo diciendo que SqlDbType.Xml - "El argumento especificado estaba fuera del rango de valores válidos.Nombre del parámetro: @xmldoc: enumeración SqlDbType no válida valor: 25 "<- Parece que enum Xml para SqlDbType no existe – Jacob

+1

No me di cuenta de que era Compact Framework. Tendría que mirar las reglas de CF antes de alterar el ejercicio. Es un subconjunto de la funcionalidad en el .NET Framework completo. –

0

lugar de utilizar el método Add, trate de usar AddWithValue donde no es necesario especificar el tipo sólo el nombre y el valor. ¿A menos que estés usando una dirección diferente para ingresar?

+0

I ' Lo intenté, pero me dio una pista. Al depurarlo, me di cuenta de que piensa que el valor es NVarChar, por lo que mi parámetro xml está en formato wrongo, uso: data.Document.ToString(), donde los datos son XDocument, ¿tal vez necesite el documento con la información de la página de códigos? – Jacob

+0

En lugar de utilizar el método .ToString() intente proporcionar el objeto real en sí, ya que AddWithValue espera un parámetro de cadena pero un valor de objeto. Hubiera pensado que luego de proporcionar su XDocument, retomaría el formato o, como usted dice, proporcionaría una página de códigos. –

-2
 
//Create The StringWriter Object 

var stringWriter = new System.IO.StringWriter(); 

//Create XmlSerializer Object for the serialization, 
RequestUpdateRBCustomerExternal is the Class of which type having all the values 

var serializer = new XmlSerializer(typeof(RequestUpdateRBCustomerExternal)); 

//request is of type RequestUpdateRBCustomerExternal 

serializer.Serialize(stringWriter, request); 

SqlXml xml = new SqlXml(new XmlTextReader(stringWriter.ToString(), XmlNodeType.Document, null)); 

cmd.CommandText ="insert into SAPDataTracking values('"+DateTime.Now+"','"+xml.Value+"')"; 
+0

IMO debe proporcionar detalles sobre su respuesta – netaholic

+0

@netaholic comentarios ya se han agregado –