1

Does anyone know how to work around the 128 character limit imposed on the ‘name’ constructor parameter (column name) of the class ‘Microsoft.SqlServer.Server.SqlMetaData’? Or know of an alternative method of returning data to the SQLPipeline, that doesn’t have a similar restriction.

Background: A number of years ago we created a .Net (C#) CLR Stored Procedure, to replace one that was implemented in vb6 and used the ‘TrueOLEDBProviderLib’ (TOLAP). The driving force behind the change was the switch to 64bit SQL Server, which meant the vb6 code could no longer run in process. (vb6 doesn’t do 64bit)

Issue: The core function of our CLR Stored Procedure is, based on a list of ‘data point identifiers’, retrieve and process data from a number of sources (DCOM components), then output a table of data to the SQLPipeline. For the table of data that is returned, we set the column name to the ‘data point identifiers’. Note: That the ‘data point identifiers’ are created based on a hierarchy, so are quite long, with a maximum length of around 256 characters.

The problem we have recently discovered, is that when attempting to output the results to the SQLPipeline, if ‘data point identifiers’ longer than 128 characters are used, then the CLR throws an exception on the length of the ‘name’ (column name). (See ‘.Net Framework Code behaviour’ below) But using the same ‘data point identifiers’ on the old vb6 CLR implementation, it works without error. With the returned table contains column names longer than 128 characters.

Supplementary Question: I know it is a different technology, but why was there no 128 character limit imposed within the SQL Server implementation of ‘TrueOLEDBProviderLib’ (TOLAP). The question I need to provide an answer to is, “if TOLAP can return tables of data that contains column names longer than 128 characters, why can’t the .Net (C#) CLR Stored Procedure”.

Workaround: The obvious fix would be to truncate the ‘data point identifiers’ down to 128 characters. However, as this is a change in functionality from the original vb6 CLR implementation, I need to explore all the alternatives first.

.Net Framework Code behaviour: Within the internal constructor of ‘SqlMetaData’, the method ‘AssertNameIsValid’ is called, where the length of the ‘name’ parameter is checked to be less than ‘SmiMetaData.MaxNameLength’ (128 character), if not an exception is thrown. https://referencesource.microsoft.com/#System.Data/fx/src/data/System/Data/Sql/SqlMetaData.cs I understand that the value of this limit is set based on the 128 character limit SQL Server has for ‘Column_Length’. https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-server-info-transact-sql?view=sql-server-ver15

** Additional Info Update: **

The old implementation was a vb6 DLL on the file system, called by a Stored Procedure.

Last version that the vb6 implementation ran on was SQL Server 2008 R2 SP2 (32bit).

The .Net CLR implementation was first run on SQL Server 2012 SP2 (64bit), current version is 2014 SP3 (64bit).

The column names ‘data point identifier’ will have all come from the SP parameters, as there is nothing like this hard coded in the vb6 version. All ‘data point identifier’ are user defined on the deployed system.

  • Hi Trevor. There are a few things going on here that don't really make sense. How is it that you were using VB6 in a SQLCLR stored procedure? Do you mean .NET code that runs _inside_ of SQL Server via loading an Assembly? Or do you mean that the VB6 code was an external app, but that functionality got moved into SQL Server? If the C# SQLCLR code was done years ago, was this limitation simply not noticed before due to not needing more than 128 characters? Can you provide an example of a column name being returned from SQL Server that is over 128 characters long? Are you using SSMS or SQLCMD? – Solomon Rutzky Mar 11 '20 at 15:48
  • Also, I don't see any way to go beyond 128 characters since SQL Server itself throws an error if you attempt to use more than that as a column alias. For example, try the following in a command prompt window: `sqlcmd -Q "EXEC(N'SELECT 1 AS [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabc];');"`. SQLCMD uses ODBC, not the .NET SqlClient. You will get an error: "Msg 103, Level 15, State 4, Server ALBRIGHT, Line 1 The identifier that starts with 'aaa...aaab' is too long. Maximum length is 128." – Solomon Rutzky Mar 11 '20 at 15:53
  • Hi Solomon The vb6 component was called from a stored procedure, created +18 years ago before we started using .Net. (Sorry I may have confused things by calling it a CLR) The vb6 code ran ‘in-process’ within SQL Server, but that only worked for 32bit SQL Server. We were very late switching to 64bit SQL Server. – Trevor McAlister Mar 11 '20 at 16:31
  • Unfortunately original testing of the .Net CLR stored procedure didn’t pickup the limitation. It was only when some client side tools that were switched over to use the stored procedure, was it noticed. I have been executing the SP direct from SSMS, just to eliminate other influences, but it can be called by other applications, including Excel queries. – Trevor McAlister Mar 11 '20 at 16:31
  • Example of an ‘data point identifier’ is: “Root.LongPlantAreaNameFolderSubLevel1.LongPlantAreaNameFolderSubLevel2.LongPlantAreaNameFolderSubLevel3.LongPlantAreaNameFolderSubLevel4.LongPlantAreaNameFolderSubLevel5.LongPlantAreaNameFolderSubLevel6.SubLevel7.Tag04.Value:value” (230 characters) – Trevor McAlister Mar 11 '20 at 16:31
  • When you say that it ran 18+ years ago _and_ "in-process", do you mean that it is an extended stored procedure? That the code is in an external DLL sitting on the file system? And, what was the last version of SQL Server to successfully execute the old VB6 code? You haven't mentioned any SQL Server version numbers, so please update the question with both the old and new version numbers. So far I am thinking that, if anything, the column names must have been stored in the VB6 code or in the driver itself as I don't see any way that SQL Server could ever handle this internally. – Solomon Rutzky Mar 11 '20 at 16:43
  • question updated – Trevor McAlister Mar 12 '20 at 14:13
  • Thanks for that info. How was the VB6 DLL called? Through an extended stored procedure or via OLE Automation procs (i.e. `sp_OA*`)? Do you still have access to an old system to test with? I just tried the test SQL I posted earlier on SQL Server 2000 and got the same Msg 103 error. I really don't see how this ever worked. Are you 100% certain that > 128 characters were returned _as a column name_? Do you have a screen shot of a long column name that isn't truncated? Also, I'm still struggling to understand how you would even use such long column names. What do you view the query in? – Solomon Rutzky Mar 12 '20 at 18:00
  • Hey Trevor. Any more info on this? I added some new questions in the comment directly above this one. – Solomon Rutzky Mar 27 '20 at 19:39

0 Answers0