C#/SQL - ¿Qué pasa con SqlDbType.Xml en los procedimientos?


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.

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. 22 feb. 092009-02-22 13:32:34

  0

Supongo que está utilizando al menos SQL2005 y que su columna está declarada como un tipo de datos XML. 22 feb. 092009-02-22 13:35:36

  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 22 feb. 092009-02-22 13:37:59

  0

¿Cómo se ve su parámetro XML y cómo lo está construyendo? 22 feb. 092009-02-22 13:50:07

  0

Este artículo puede ser de interés - http://dotnet.sys-con.com/node/406637 - todo el código está disponible a través de los hipervínculos 22 feb. 092009-02-22 13:51:33

  0

@GregD - sql2005 de hecho; no necesita columnas xml, proceso de procedimiento almacenado xml e insertar valores en culums (probado y funciona bien). @Russ Cam - Estás hablando de lado sql, para C# max es 4k. Intenté eso. 22 feb. 092009-02-22 13:53:28

  0

¿Con qué versión del marco estás intentando compilar? El SqlDatatype.Xml no existe en .NET 1.1. 22 feb. 092009-02-22 13:54:14

  0

Si se trata de un proyecto ASP.NET, vaya a la configuración de IIS y compruebe que se está ejecutando en el tiempo de ejecución correcto. 22 feb. 092009-02-22 13:56:20

  0

Compact Framewrok 3.5 22 feb. 092009-02-22 13:57:31

  0

@ Jacob- El otro día escribí una aplicación de consola C# de ejemplo para demostrarle a un colega que puede pasar una cadena NVARCHAR superior a 4000 en un procedimiento almacenado. Por lo tanto, estoy convencido de que puedes hacerlo. Debe seleccionar el tipo de CLR correcto para asignar al tipo de SQL NVARCHAR (MAX) 22 feb. 092009-02-22 14:00:07

  0

¿Cuál es el tipo del objeto de comando? 22 feb. 092009-02-22 14:01:37

  0

Puede utilizar el método SqlCommand.Parameters.AddWithValue, que creo que deja el marco para inferir el tipo de datos del parámetro 22 feb. 092009-02-22 14:05:04

  0

si usa los parámetros SqlCommand.Parameters.Agregar método, entonces creo que el SQLDbtype correcto para utilizar para NVARCHAR (MAX) es NTEXT 22 feb. 092009-02-22 14:15:12

  0

Básicamente, los más nuevos VARCHAR (MAX), NVARCHAR (MAX) y VARBINARIO (MAX) mapeados a SQLDBTypes TEXT, NTEXT e IMAGE, respectivamente 22 feb. 092009-02-22 14:19:19

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 22 feb. 092009-02-22 16:33:18

+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. 25 feb. 092009-02-25 16:31:37


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? 22 feb. 092009-02-22 14:15:48

  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. 22 feb. 092009-02-22 14:32:33


-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 21 sep. 152015-09-21 15:02:06

  0

@netaholic comentarios ya se han agregado 22 sep. 152015-09-22 04:27:01