Bug 43795 - Wrong max. size for System.Data.SqlClient.SqlParameter of type NVarchar
Summary: Wrong max. size for System.Data.SqlClient.SqlParameter of type NVarchar
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.Data (show other bugs)
Version: unspecified
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-08-26 16:07 UTC by Kai M. Wadsack
Modified: 2017-09-01 09:29 UTC (History)
1 user (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
StackTrace (2.75 KB, text/plain)
2016-08-26 16:07 UTC, Kai M. Wadsack
Details

Description Kai M. Wadsack 2016-08-26 16:07:22 UTC
Created attachment 17222 [details]
StackTrace

Microsoft .NET supports a max size of a SqlParameter of type NVarChar up to 2147483647.
Max. size in Mono for a SqlParameter of type NVarChar is 1073741823.

This incompatibility leads to a problem when using an OR Mapper like e.g. LLBLGen as they use the max size defined by Microsoft in the SqlParameter declaration. So any attempt to update or insert a table field of type NVarChar(max) leads to a TDS parser exception.

Steps to reproduce the bug:

First of all a small SQL Script to create a DB and a table, so that we've got something to test with:

USE master
GO

CREATE LOGIN DebugUser WITH PASSWORD=N'monotest', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO

CREATE DATABASE TestDB
GO

USE TestDB
GO

CREATE USER DebugUser FOR LOGIN DebugUser
GO

ALTER ROLE [db_owner] ADD MEMBER [DebugUser]
GO

CREATE TABLE NVarCharTest
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[LongName] [nvarchar](MAX) NOT NULL
)
GO

ALTER TABLE NVarcharTest ADD CONSTRAINT PK_NVarcharTest PRIMARY KEY ([Id])
GO

Next create a console application, name it "TestNVarCharMax", add a reference to System.Data to the project and overwrite the content of Program.cs with the following code:

Code:

using System.Data.SqlClient;
using System.Data;
using System;

namespace TestNVarCharMax {
    class MainClass {
        static string ConnectionString =
            @"data source=localhost;initial catalog=TestDB;User ID=DebugUser;Password=monotest;persist security info=False;packet size=4096;Connection Timeout=300";

        public static void Main() {

            const string commandText = @"INSERT INTO NVarCharTest (LongName) VALUES (@LongName)";
            const int maxNVarCharLengthDotNet = 2147483647;
            const int maxNVarCharLengthMono = 1073741823;

            using (var connection = new SqlConnection(ConnectionString)) {
                connection.Open();
                using (var command = new SqlCommand(commandText, connection)) {
                    var longNameParameter = new SqlParameter("@LongName", SqlDbType.NVarChar, maxNVarCharLengthDotNet);
                    longNameParameter.Value = @"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.";

                    command.Parameters.Add(longNameParameter);

                    try {
                        command.ExecuteNonQuery();
                    }
                    catch (Exception ex) {
                        Console.WriteLine(ex.Message);
                        Console.WriteLine(ex.StackTrace);
                    }

                    longNameParameter.Size = maxNVarCharLengthMono;

                    try {
                        command.ExecuteNonQuery();
                    }
                    catch (Exception ex) {
                        Console.WriteLine(ex.Message);
                        Console.WriteLine(ex.StackTrace);
                    }
                }
            }
        }
    }
}

Replace "localhost" in the connection string with ip address, name or instance name of your sql server.

Running the code under mono, line #25 of above code will give you the following error message:

Der eingehende Tabular Data Stream (TDS) für das RPC-Protokoll (Remote Procedure Call) ist nicht richtig. Parameter 3 ('@LongName'): Der 0xE7-Datentyp hat eine ungültige Datenlänge oder Metadatenlänge.

English translation: 

The incoming Tabular Data Stream (TDS) for the RPC protocol (Remote Procedure Call) is not correct. Parameter 3 ('@LongName'): The 0xE7-datatype has an invalid data length or metadata length.

Stack trace is attached.

Running the same code under .NET on Windows doesn't throw any errors.

Note You need to log in before you can comment on or make changes to this bug.