Sql-server – NVARCHAR(MAX) – As SQL Stored Procedure Output Parameter

sql serversql-server-2008sqlapi++stored-procedures

Display_Info is a SQL stored procedure,has three input parameters and three output parameters. info_Data(serialized information data may also contain unicode and null values) one of the output parameters is of type NVARCHAR(1000) previously. Since the larger the size of info_Data now it is changed of type NVARCHAR(MAX). When it was like NVARCHAR(1000) there was no problem in executing the stored procedure in client application, but after changing it to NVARCHAR(MAX) the client application is throwing the error like "At least one parameter contained a type that was not supported.". SQL stored procedure design is as shown below.

Create Display_Info @channel NVARCHAR(100)
    ,@infoType INT
    ,@locationId NVARCHAR(50)
    ,@Id BIGINT OUTPUT
    ,@infoData NVARCHAR(MAX) OUTPUT
    ,@infoStatus TINYINT OUTPUT
AS
...

The way the client application executing the stored procedure is,

try
{
SACommand conncmd;
CheckConnection();
conncmd.setConnection(&mConn);
std::wstring cmdText = COMMAND_TEXT("ReadMessage");
conncmd.setCommandText(cmdText.c_str());
conncmd.Param("channel").setAsString() = SAString(channel.c_str(), (int)channel.length());
conncmd.Param("infoType").setAsNumeric() = SANumeric((sa_int64_t)type);
conncmd.Param("locationId").setAsString() = SAString(locationId.c_str(), (int)locationId.length());
conncmd.Execute(); 
std::wstring Id = conncmd.Param(COMMAND_TEXT("Id")).asString();
infodata = conncmd.Param(COMMAND_TEXT("info_Data")).asString();
}
catch (SAException &e)
{
std::string errorMessage = (mb_twine)e.ErrText();
std::cout << "\n" <<errorMessage;
}

Sample Input/output:

infoData serialized input : Total length 5191

Ä(Á(¼(Protocol Buffers is a method of serializing structured data. It is useful in developing programs to communicate with each other over a wire or for storing data. The method involves an interface description language that describes the structure of some data and a program that generates source code from that description for generating or parsing a stream of bytes that represents the structured data.Google developed Protocol Buffers for use internally and has made protocol compilers for C++, Java and Python available to the public under a free software, open source license. Various other language implementations are also available, including C#, JavaScript, Go, Perl, PHP, Ruby, and Scala.[1]The design goals for Protocol Buffers emphasized simplicity and performance. In particular, it was designed to be smaller and faster than XML.[2] Third parties have reported that Protocol Buffers outperforms the standardized Abstract Syntax Notation One with respect to both message size and decoding performance.[3]Protocol Buffers is widely used at Google for storing and interchanging all kinds of structured information. The method serves as a basis for a custom remote procedure call (RPC) system that is used for nearly all inter-machine communication at Google.[4]Protocol Buffers is very similar to the Apache Thrift protocol (used by Facebook for example), except that the public Protocol Buffers implementation does not include a concrete RPC protocol stack to use for defined services.A software developer defines data structures (called messages) and services in a proto definition file (.proto) and compiles it with protoc. This compilation generates code that can be invoked by a sender or recipient of these data structures. For example, example.proto will produce example.pb.cc and example.pb.h, which will define C++ classes for each message and service that example.proto defines.Canonically, messages are serialized into a binary wire format which is compact, forwards-compatible, and backwards-compatible, but not self-describing (that is, there is no way to tell the names, meaning, or full datatypes of fields without an external specification). There is no defined way to include or refer to such an external specification (schema) within a Protocol Buffers file. The officially supported implementation includes an ASCII serialization format,[5] but this format â though self-describing â loses the forwards-and-backwards-compatibility behavior, and is thus not a good choice for applications other than debugging.Though the primary purpose of Protocol Buffers is to facilitate network communication, its simplicity and speed make Protocol Buffers an alternative to data-centric C++ classes and structs, especially where interoperability with other languages or systems might be needed in the future.A schema for a particular use of protocol buffers associates data types with field names, using integers to identify each field. (The protocol buffer data contains only the numbers, not the field names, providing some bandwidth / storage savings compared with systems that include the field names in the data.)//polyline.protomessage Point {  required int32 x = 1;    required int32 y = 2;   optional string label = 3;   }      message Line {     required Point start = 1;    required Point end = 2;      optional string label = 3;   }      message Polyline {     repeated Point point = 1;       optional string label = 2;    }    The "Point" message defines two mandatory data items, x and y. The data item label is optional. Each data item has a tag. The tag is defined after the equal sign. For example, x has the tag 1.        The Line and "Polyline" messages, which both use Point, demonstrate how composition works in Protocol Buffers. Polyline has a repeated field, which behaves like a vector.        This schema can subsequently be compiled for use by one or more programming languages. Google provides a compiler called protoc which can produce output for C++, Java or Python. Other schema compilers are available from other sources to create language-dependent output for over 20 other languages.[6]        For example, after a C++ version of the protocol buffer schema above is produced, a C++ source code file, polyline.cpp, can use the message objects as follows:        // polyline.cpp#include polyline.pb.h  // generated by calling protoc polyline.proto        Line* createNewLine(const std::string& name) {      // create a line from (10, 20) to (30, 40)        Line* line = new Line;       line->mutable_start()->set_x(10);         line->mutable_start()->set_y(20);        line->mutable_end()->set_x(30);          line->mutable_end()->set_y(40);         line->set_label(name);           return line;        }                Polyline* createNewPolyline() {          // create a polyline with points at (10,10) and (20,20)            Polyline* polyline = new Polyline;           Point* point1 = polyline->add_point();             point1->set_x(10);            point1->set_y(10);              Point* point2 = polyline->add_point();             point2->set_x(20);               point2->set_y(20);              return polyline;              }

When, NVARCHAR(1000), infoData value : Total length – 1003

Ä(Á(¼(Protocol Buffers is a method of serializing structured data. It is useful in developing programs to communicate with each other over a wire or for storing data. The method involves an interface description language that describes the structure of some data and a program that generates source code from that description for generating or parsing a stream of bytes that represents the structured data.Google developed Protocol Buffers for use internally and has made protocol compilers for C++, Java and Python available to the public under a free software, open source license. Various other language implementations are also available, including C#, JavaScript, Go, Perl, PHP, Ruby, and Scala.[1]The design goals for Protocol Buffers emphasized simplicity and performance. In particular, it was designed to be smaller and faster than XML.[2] Third parties have reported that Protocol Buffers outperforms the standardized Abstract Syntax Notation One with respect to both message size and dec

when NVARCHAR(4000), infoData : Total length – 4084

Ä(Á(¼(Protocol Buffers is a method of serializing structured data. It is useful in developing programs to communicate with each other over a wire or for storing data. The method involves an interface description language that describes the structure of some data and a program that generates source code from that description for generating or parsing a stream of bytes that represents the structured data.Google developed Protocol Buffers for use internally and has made protocol compilers for C++, Java and Python available to the public under a free software, open source license. Various other language implementations are also available, including C#, JavaScript, Go, Perl, PHP, Ruby, and Scala.[1]The design goals for Protocol Buffers emphasized simplicity and performance. In particular, it was designed to be smaller and faster than XML.[2] Third parties have reported that Protocol Buffers outperforms the standardized Abstract Syntax Notation One with respect to both message size and decoding performance.[3]Protocol Buffers is widely used at Google for storing and interchanging all kinds of structured information. The method serves as a basis for a custom remote procedure call (RPC) system that is used for nearly all inter-machine communication at Google.[4]Protocol Buffers is very similar to the Apache Thrift protocol (used by Facebook for example), except that the public Protocol Buffers implementation does not include a concrete RPC protocol stack to use for defined services.A software developer defines data structures (called messages) and services in a proto definition file (.proto) and compiles it with protoc. This compilation generates code that can be invoked by a sender or recipient of these data structures. For example, example.proto will produce example.pb.cc and example.pb.h, which will define C++ classes for each message and service that example.proto defines.Canonically, messages are serialized into a binary wire format which is compact, forwards-compatible, and backwards-compatible, but not self-describing (that is, there is no way to tell the names, meaning, or full datatypes of fields without an external specification). There is no defined way to include or refer to such an external specification (schema) within a Protocol Buffers file. The officially supported implementation includes an ASCII serialization format,[5] but this format â though self-describing â loses the forwards-and-backwards-compatibility behavior, and is thus not a good choice for applications other than debugging.Though the primary purpose of Protocol Buffers is to facilitate network communication, its simplicity and speed make Protocol Buffers an alternative to data-centric C++ classes and structs, especially where interoperability with other languages or systems might be needed in the future.A schema for a particular use of protocol buffers associates data types with field names, using integers to identify each field. (The protocol buffer data contains only the numbers, not the field names, providing some bandwidth / storage savings compared with systems that include the field names in the data.)//polyline.protomessage Point {  required int32 x = 1;    required int32 y = 2;   optional string label = 3;   }      message Line {     required Point start = 1;    required Point end = 2;      optional string label = 3;   }      message Polyline {     repeated Point point = 1;       optional string label = 2;    }    The "Point" message defines two mandatory data items, x and y. The data item label is optional. Each data item has a tag. The tag is defined af

when NVARCHAR(MAX) :
with same infoData input
After executing the command,

conncmd.Execute(); // after this statement 

it throws an error like

At least one parameter contained a type that was not supported.

From the error it is understood very clear that, this type will not be supported anymore. Also While explicitly executing the stored procedure in SQL Server Management Studio. It is working fine, Got the complete infoData without any truncation.

USE [TestDB]
GO

DECLARE @return_value int,
        @Id bigint,
        @infoData nvarchar(max),
        @infoStatus tinyint

EXEC    @return_value = "DisplayInfo"
        @channel = N'telephoneMessage',
        @infoType = 1,
        @locationId = N'F6C8B935',
        @Id = @Id OUTPUT,
        @infoData = @infoData OUTPUT,
        @infoStatus = @infoStatus OUTPUT

SELECT  @Id as N'@PayloadId',
        @infoData as N'@MessageData',
        @infoStatus as N'@Status'

SELECT  'Return Value' = @return_value

GO

I have also noted that What is the maximum characters for the NVARCHAR(MAX)? which is saying that "The max size for a column of type NVARCHAR(MAX) is 2 GByte of storage". But I don't understand then Why in this case it is showing the NVARCHAR(MAX) as Type not supported. I have mentioned the SSMS version I am using so that it may helps to fix the error accurately.

SQL server Management Studio 2008 R2. V 10.50.2550.0:
SQLAPI++ – 3.8.3

Help me get the complete info_Data as it is without any loss or truncation.

Thanks in Advance.

Best Answer

The truth is, that you cannot have in a query variable with 2GB of information.

The max size for a column of type NVARCHAR(MAX) in a query is 4000 characters (1 LOB page), even in the SSMS query window ;-).

So, you don't need to use that (MAX) at all.

Different case is, when you have column in a table as NVARCHAR(MAX). In that case you can have up to 2GB information in there, that is saved in multiple LOB pages.

More information https://social.msdn.microsoft.com/Forums/sqlserver/en-US/d5e0c6e5-8e44-4ad5-9591-20dc0ac7a870/nvarcharmax?forum=transactsql