C#/SQL - Co jest nie tak z SqlDbType.Xml w procedurach?


5

Poprosiłem kilka osób, dlaczego używanie xml jako parametru w procedurze przechowywanej nie działa i wszyscy mówili, że tak właśnie jest. Nie mogę tego uwierzyć.

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

To gdzie kompilator zwróci błąd i nie można użyć nvarchar beacouse to limiteed do 4k śpiewa. XML byłby idealny, ponieważ może mieć 2 gigigi.

W jaki sposób inne SqlDbTypes działają dobrze i ten jeden retruns błąd?

*

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

*

  0

może być dobrym rozwiązaniem, aby dołączyć błąd do wiadomości. 22 lut. 092009-02-22 13:32:34

  0

Zakładam, że używasz co najmniej SQL2005 i że twoja kolumna jest zadeklarowana jako typ danych XML? 22 lut. 092009-02-22 13:35:36

  0

jeśli używasz programu SQL Server 2005 lub nowszego, istnieje większy limit wielkości łańcuchów znaków NVARCHAR. Zobacz słowo kluczowe MAX - http://msdn.microsoft.com/en-us/library/ms186939.aspx - MAX wskazuje, że maksymalna długość dla NVARCHAR wynosi 1 073 747 822 22 lut. 092009-02-22 13:37:59

  0

Jak wygląda twój parametr XML i jak go konstruujesz? 22 lut. 092009-02-22 13:50:07

  0

Ten artykuł może być interesujący - http://dotnet.sys-con.com/node/406637 - cały kod jest dostępny poprzez hiperłącza 22 lut. 092009-02-22 13:51:33

  0

@GregD - sql2005 w rzeczy samej; nie potrzebuję kolumn xml, procesu przechowywanego xml procesu i wstaw wartości do culums (testowane i działa dobrze). @Russ Cam - Mówisz o stronie sql, dla C# max jest 4k. Próbowałem tego. 22 lut. 092009-02-22 13:53:28

  0

Z jaką wersją frameworka próbujesz się skompilować? SqlDatatype.Xml nie istnieje w .NET 1.1. 22 lut. 092009-02-22 13:54:14

  0

Jeśli jest to projekt ASP.NET, przejdź do ustawień IIS i sprawdź, czy działasz w poprawnym środowisku wykonawczym. 22 lut. 092009-02-22 13:56:20

  0

Kompaktowy Framewrok 3.5 22 lut. 092009-02-22 13:57:31

  0

@ Jacob- Napisałem przykładową aplikację C# na drugi dzień, aby zademonstrować koledze, że można przekazać więcej niż 4000 długości łańcucha NVARCHAR do procedury składowanej. Dlatego jestem nieugięty, że możesz to zrobić. Musisz wybrać poprawny typ CLR, aby odwzorować na typ SQL NVARCHAR (MAX) 22 lut. 092009-02-22 14:00:07

  0

Jaki jest typ obiektu polecenia? 22 lut. 092009-02-22 14:01:37

  0

Można użyć metody SqlCommand.Parameters.AddWithValue, co, jak sądzę, pozostawia ramy do wnioskowania o typie danych parametru 22 lut. 092009-02-22 14:05:04

  0

W przypadku używania parametrów SqlCommand.Parameters.Dodaj metodę, to wierzę, że poprawny typ SQLDbity do użycia dla NVARCHAR (MAX) to NTEXT 22 lut. 092009-02-22 14:15:12

  0

Zasadniczo nowszy VARCHAR (MAX), NVARCHAR (MAX) i VARBINARY (MAX) zmapowany do SQLDBTypes TEXT, NTEXT i IMAGE, odpowiednio 22 lut. 092009-02-22 14:19:19

13

To działa. Będziesz musiał ustawić wartość jako SqlXml, a nie ciąg znaków, ale można to zrobić. Wyobraź sobie taką tabelę:

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

a sproc:

CREATE PROCEDURE XmlTest_Insert 
(
    @XmlText xml 
) 
AS 

INSERT INTO XmlTest (XmlText) 
VALUES (@XmlText) 

Teraz obraz aplikację konsoli, który wygląda tak:

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!

Dokonano tego w Visual Studio 2008 (.NET 3.5), ale jestem dość pewny, że powinien działać również w Visual Studio 2005 (2.0 Framework).

  0

Twój przykład działa poprawnie, jak powinien, , ale kiedy wypróbuję go w mojej aplikacji CF 3.5, ciągle powtarza, że ​​SqlDbType.Xml - "Podany argument był poza zakresem prawidłowych wartości. Nazwa parametru: @xmldoc: Nieprawidłowe wyliczenie SqlDbType wartość: 25 "<- Wygląda jak enum Xml dla SqlDbType nie istnieje 22 lut. 092009-02-22 16:33:18

+1

Nie wiedziałem, że to Compact Framework. Zanim zmienię ćwiczenie, będę musiał przyjrzeć się regułom CF. Jest to podzbiór funkcjonalności w pełnym .NET Framework. 25 lut. 092009-02-25 16:31:37


0

Zamiast metody Add, spróbuj użyć AddWithValue gdzie nie trzeba określić typ tylko nazwę i wartość. O ile nie używasz innego kierunku do wprowadzania?

  0

I ' próbowałem tego, ale dało mi to wskazówkę. Podczas debugowania zauważyłem, że sądzi on, że wartość jest NVarChar, więc mój parametr xml jest w formacie wrongo, używam: data.Document.ToString(), gdzie dane to XDocument, może potrzebuje on dokumentu z informacjami o stronie kodowej? 22 lut. 092009-02-22 14:15:48

  0

Zamiast używać metody .ToString() należy podać rzeczywisty obiekt, ponieważ AddWithValue oczekuje parametru tekstowego, ale wartości obiektu. Pomyślałabym, że wtedy dostarczając twój XDocument, wziąłby on format, lub jak mówisz, podaj stronę kodową. 22 lut. 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 powinieneś podać szczegółowe informacje na temat swojej odpowiedzi 21 wrz. 152015-09-21 15:02:06

  0

@newaholic komentarze są już dodane 22 wrz. 152015-09-22 04:27:01