2009-02-22 3 views
5

J'ai demandé à peu de gens pourquoi l'utilisation de xml en tant que paramètre dans une procédure stockée ne fonctionne pas et tout le monde a dit, c'est comme ça. Je ne peux pas croire ça.C#/SQL - Quel est le problème avec SqlDbType.Xml dans les procédures?

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

Ce compilateur est où renvoie l'erreur et je ne peux pas utiliser NVarChar beacouse il est limiteed 4K chante. XML serait parfait car il peut être 2gigs grand.

Comment les autres SqlDbTypes fonctionnent-ils bien et celui-ci retruns erreur?

*

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

*

+0

peut être bon d'attacher l'erreur le cas échéant à la publication. –

+0

Je suppose que vous utilisez au moins SQL2005 et que votre colonne est déclarée comme un type de données XML? Si vous utilisez SQL Server 2005 à partir de – GregD

+0

, la taille des chaînes NVARCHAR est limitée. Voir le mot-clé MAX - http://msdn.microsoft.com/en-us/library/ms186939.aspx - MAX indique que la longueur maximale pour NVARCHAR est de 1 073 741 822 –

Répondre

13

Cela fonctionne. Vous devrez configurer la valeur comme SqlXml et pas une chaîne, mais cela peut être fait. Imaginez ce tableau:

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

Et le sproc:

CREATE PROCEDURE XmlTest_Insert 
(
    @XmlText xml 
) 
AS 

INSERT INTO XmlTest (XmlText) 
VALUES (@XmlText) 

image maintenant une application console qui ressemble à ceci:

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!

Cela a été fait dans Visual Studio 2008 (.NET 3.5), mais je suis assez sûr qu'il devrait fonctionner dans Visual Studio 2005 (2.0 Framework), aussi bien.

+0

Votre exemple fonctionne absolument bien comme il se doit, bien que lorsque je l'essaie sur mon application CF 3.5, il continue à dire que SqlDbType.Xml - "L'argument spécifié était hors de la plage des valeurs valides.Nom du paramètre: @xmldoc: Invalid SqlDbType énumération value: 25 "<- On dirait que enum Xml pour SqlDbType n'existe pas – Jacob

+1

Je n'avais pas réalisé que c'était Compact Framework. Je devrais examiner les règles de CF avant de modifier l'exercice. C'est un sous-ensemble de la fonctionnalité dans le .NET Framework complet. –

0

Au lieu d'utiliser la méthode Ajouter, essayez d'utiliser AddWithValue où vous n'avez pas besoin de spécifier le type juste le nom et la valeur. Sauf si vous utilisez une direction différente pour entrer?

+0

I ' J'ai essayé ça, mais ça m'a donné une idée. Pendant le débogage, j'ai remarqué qu'il pense que la valeur est NVarChar, donc mon paramètre xml est au format incorrect, j'utilise: data.Document.ToString(), où data est XDocument, peut-être a-t-il besoin du doc ​​avec info page? – Jacob

+0

Au lieu d'utiliser la méthode .ToString(), essayez de fournir l'objet lui-même, car AddWithValue attend un paramètre de chaîne, mais une valeur d'objet. J'aurais pensé que si vous fournissiez votre XDocument, il reprendrait le format ou, comme vous le dites, fournirait une page de codes. –

-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 vous devriez fournir des détails sur votre réponse – netaholic

+0

@netaholic commentaires sont déjà ajoutés –

Questions connexes