C#/SQL - Quel est le problème avec SqlDbType.Xml dans les procédures?


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.

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

  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 22 févr.. 092009-02-22 13:35:36

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

  0

A quoi ressemble votre paramètre XML et comment le construisez-vous? 22 févr.. 092009-02-22 13:50:07

  0

Cet article peut être intéressant - http://dotnet.sys-con.com/node/406637 - tout le code est disponible via des hyperliens 22 févr.. 092009-02-22 13:51:33

  0

@GregD - sql2005 en effet; n'ont pas besoin de colonnes xml, de processus de procédure stockés xml et d'insertion de valeurs dans les culums (testés et fonctionnent correctement). @Russ Cam - Vous parlez de sql side, car C# max est 4k. J'ai essayé ça. 22 févr.. 092009-02-22 13:53:28

  0

Avec quelle version du framework essayez-vous de compiler? Le SqlDatatype.Xml n'existe pas dans .NET 1.1. 22 févr.. 092009-02-22 13:54:14

  0

S'il s'agit d'un projet ASP.NET, accédez aux paramètres IIS et vérifiez que vous exécutez sous le bon runtime. 22 févr.. 092009-02-22 13:56:20

  0

Compact Framewrok 3.5 22 févr.. 092009-02-22 13:57:31

  0

@ Jacob- J'ai écrit un exemple d'application console C# l'autre jour pour démontrer à un collègue que vous pouvez passer plus de 4000 longueur de chaîne NVARCHAR dans une procédure stockée. Par conséquent, je suis catégorique que vous pouvez le faire. Vous devez sélectionner le type CLR correct à mapper au type SQL NVARCHAR (MAX) 22 févr.. 092009-02-22 14:00:07

  0

Quel est le type de l'objet de commande? 22 févr.. 092009-02-22 14:01:37

  0

Vous pouvez utiliser la méthode SqlCommand.Parameters.AddWithValue, qui, selon moi, quitte l'infrastructure pour déduire le type de données du paramètre 22 févr.. 092009-02-22 14:05:04

  0

Si vous utilisez la commande SqlCommand.Parameters.Ajouter méthode, alors je crois que le bon SQLDbtype à utiliser pour NVARCHAR (MAX) est NTEXT 22 févr.. 092009-02-22 14:15:12

  0

Fondamentalement, le plus récent VARCHAR (MAX), NVARCHAR (MAX) et VARBINARY (MAX) mappé à SQLDBTypes TEXT, NTEXT et IMAGE, respectivement 22 févr.. 092009-02-22 14:19:19

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

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


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

  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. 22 févr.. 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 vous devriez fournir des détails sur votre réponse 21 sept.. 152015-09-21 15:02:06

  0

@netaholic commentaires sont déjà ajoutés 22 sept.. 152015-09-22 04:27:01