in

UGISS Community

Il sito della community dello User Group Italiano di SQL Server

Problema su variabili dichiarate varchar(8000)

Last post 01-23-2008 12.45 by Keylog. 8 replies.
Page 1 of 1 (9 items)
Sort Posts: Previous Next
  • 01-22-2008 13.01

    • Keylog
    • Top 50 Contributor
    • Joined on 06-04-2007
    • Posts 13
    • Points 215

    Problema su variabili dichiarate varchar(8000)

    Ciao a tutti,

    ho scoperto che in stored procedures in cui ho dichiarato variabili varchar(8000), il numero dei caratteri restituiti è sempre 4000 anche se il set è superiore; è mai capitato a qualcun altro oltre me?

    Le procedure girano su un'installazione SQL Server 2000 Standard Edition SP3a; anticipo che tra i vari bug fixes del SP4 non ho trovato nessun elemento che risolva il problema o per lo meno lo denunci. 

    Grazie 1000 per l'eventuale aiuto

    Marco 

    Filed under: ,
    • Post Points: 35
  • 01-22-2008 13.25 In reply to

    • lbenaglia
    • Top 25 Contributor
      Male
    • Joined on 05-14-2007
    • Vimercate (Milano)
    • Posts 79
    • Points 1.170

    Re: Problema su variabili dichiarate varchar(8000)

    Keylog:
    ho scoperto che in stored procedures in cui ho dichiarato variabili varchar(8000), il numero dei caratteri restituiti è sempre 4000 anche se il set è superiore; è mai capitato a qualcun altro oltre me?

    Ciao Marco,

    Se quelle variabili le valorizzi tramite query, come sono definite le colonne delle tabelle base da cui prelevi i dati?
    Diversamente prova a postare un esempio completo che riproduca l'anomalia.

    Ciao!

    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://italy.mvps.org
    • Post Points: 20
  • 01-22-2008 14.02 In reply to

    Re: Problema su variabili dichiarate varchar(8000)

    Keylog:
    ho scoperto che in stored procedures in cui ho dichiarato variabili varchar(8000), il numero dei caratteri restituiti è sempre 4000 anche se il set è superiore

    Potrebbe essere un problema legato a variabili unicode ?

     

    Franco Pigoli
    Consulente IT ( .Net, SAS, SqlServer) & Analisi dati
    • Post Points: 20
  • 01-23-2008 9.12 In reply to

    • Keylog
    • Top 50 Contributor
    • Joined on 06-04-2007
    • Posts 13
    • Points 215

    Re: Problema su variabili dichiarate varchar(8000)

    Non credo, la variabile è costruita per creare a runtime tabelle che ridondano dati da tabelle esistenti in produzione, le variabili sono dichiarate semplicemente varchar(8000); mi ricordo che anche una volta installato il SP4 non risolvevo comunque il problema. La cosa incredibile è che tale procedura è presente su 4 server per 6 istanze ed in tutte le macchine si comporta allo stesso modo, troncando il contenuto a 4000 caratteri. Tutte le istanze sono Standard Edition SP3a.

    Marco 

    Filed under: ,
    • Post Points: 35
  • 01-23-2008 9.33 In reply to

    Re: Problema su variabili dichiarate varchar(8000)

    La cosa e' intrigante, io non sono riuscito a riprodurla... Non riesci a mandarci codice e dati per poterlo lanciare anche noi ?

    Franco Pigoli
    Consulente IT ( .Net, SAS, SqlServer) & Analisi dati
    • Post Points: 5
  • 01-23-2008 9.49 In reply to

    • sgovoni
    • Top 10 Contributor
      Male
    • Joined on 10-18-2007
    • Posts 141
    • Points 2.155

    Re: Problema su variabili dichiarate varchar(8000)

    Marco Ciao,

    non mi è chiaro se le variabili VARCHAR(8000) vengono usate solo all'interno di stored procedure (eseguite con un job o manualmente) oppure se vengono passate come parametri o restituite come output ad una applicazione. Se c'è una applicazione di mezzo che utilizza DB-Library tieni conto di questa nota che ho trovato sui Books Online cercando "Using char and varchar Data":

    "DB-Library applications and applications using the SQL Server ODBC drivers from SQL Server version 6.5 or earlier support only a maximum of 255 bytes of character data. If these applications attempt to retrieve character parameters of SQL Server version 7.0 or later, or result set columns containing more than 255 bytes of data, the character data is truncated at 255 bytes."

    Quale collation usi per il tuo database ?

    Ciao!

    Sergio

    Filed under: ,
    • Post Points: 5
  • 01-23-2008 10.01 In reply to

    • Keylog
    • Top 50 Contributor
    • Joined on 06-04-2007
    • Posts 13
    • Points 215

    Re: Problema su variabili dichiarate varchar(8000)

     Ciao Lorenzo, ti posto il codice della funzione, che è molto semplice; in pratica gli passi il nome di una tabella e la funzione la ricrea aggiungendo in più la parte di controllo, il punto in cui presenta l'anomalia è quando effettua la concatenazione di stringa delle colonne.

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO

    ALTER function [dbo].[F_GENERA_CREATE_TABLE] (@tab sysname) returns varchar(8000)
    as
    /******************************************************************************
    **      Desc: Genera lo script di creazione tabella
    **      Versione script: 1.0
    **      Chiamata da:
    **
    **      Parametri:
    **      Input                           Output
    **      Nome Tabella                    Campi della tabella
    **
    **      Autore: Stefano di Pace
    **      Data creaz: 14 maggio 2004
    *******************************************************************************
    **      Storia delle Modifiche
    *******************************************************************************
    **      Data:            Autore:             Descrizione:
    **      14 maggio 2004   Stefano di Pace
    **      03 agosto 2005   Marco Fusco         Reso dinamico il nome delle colonne
    **                                           da creare nella trac e non esistenti
    **                                           in quelle di partenza
    **      23 ottob  2007   Stefano di Pace     Escluse le colonne con datatype text, ntext, image
    **      31 ottob  2007   Stefano di Pace     Gestione della stringa di ritorno modificata
    *******************************************************************************/
    Begin

        declare  @vcStrColumns  varchar(6000)
                ,@vcStrPre      varchar(2000)
                ,@vcRetStrSql   varchar(8000)
                ,@iPrefixPos    int
                ,@vPrefixTbName varchar(50)

        set @iPrefixPos = charindex('_',@tab,4)
        set @vcStrColumns = ''
       
        if @iPrefixPos = 0
           set @vPrefixTbName = @tab+'_'
        else
           set @vPrefixTbName = left(@tab,@iPrefixPos)

        set @vcStrPre = 'if exists (select 1 from information_schema.tables where table_name = ''' + @tab + '_trac''' + ')' + char(13)
        set @vcStrPre = @vcStrPre + 'Begin' + char(13)
        set @vcStrPre = @vcStrPre + 'drop table ' + 'dbo.'+ @tab + '_trac' + char(13)
        set @vcStrPre = @vcStrPre + 'End' + char(13)
        set @vcStrPre = @vcStrPre + 'create table ' + 'dbo.'+ @tab + '_trac (' + char(13)
        set @vcStrPre = @vcStrPre + @vPrefixTbName + 'trac_id int identity (1,1) primary key,' + char(13)
        set @vcStrPre = @vcStrPre + @vPrefixTbName + 'funzio_codice_trac varchar(50),' + char(13)
       
        select @vcStrColumns = @vcStrColumns + column_name + '_trac ' + case data_type
                                                                             when 'varchar' then data_type + '(' + cast(character_maximum_length as varchar(4)) + '),' + char(13)
                                                             when 'nvarchar' then data_type + '(' + cast(character_maximum_length as varchar(4)) + '),' + char(13)
                                                                             when 'char' then data_type + '(' + cast(character_maximum_length as varchar(4)) + '),'+ char(13)
                                                             when 'nchar' then data_type + '(' + cast(character_maximum_length as varchar(4)) + '),'+ char(13)
                                                             --when 'text' then data_type + ',' + char(13)
                                                             --when 'ntext' then data_type + ',' + char(13)
                                                             when 'decimal' then data_type + '(' + cast(numeric_precision as varchar(4)) + ',' + cast(numeric_scale as varchar(4)) + '),'+ char(13)
                                                             when 'numeric' then data_type + '(' + cast(numeric_precision as varchar(4)) + ',' + cast(numeric_scale as varchar(4)) + '),'+ char(13)
                                                             when 'float' then data_type + '(' + cast(numeric_precision as varchar(4)) + '),'+ char(13)
                                                                             when 'real' then data_type + '(' + cast(numeric_precision as varchar(4)) + '),'+ char(13)
                                                             when 'money' then data_type + ',' + char(13)
                                                             when 'smallmoney' then data_type +  ',' + char(13)
                                                             when 'int' then data_type + ',' + char(13)
                                                             when 'bigint' then data_type + ','+ char(13)
                                                                 when 'tinyint' then data_type + ','+ char(13)
                                                             when 'smallint' then data_type + ','+ char(13)
                                                             when 'datetime' then data_type + ','+ char(13)
                                                             when 'smalldatetime' then data_type + ','+ char(13)
                                                             when 'bit' then data_type + ','+ char(13)
                                                             else 'ALTRO'
                                                               end
         from information_schema.tables a
                inner join information_schema.columns b on a.table_name = b.table_name
        where a.table_type = 'BASE TABLE'
          and a.table_name = @tab
    /* 23-10-2007 */
          and data_type not in ('text','ntext','image')
    /* 23-10-2007 */
        order by a.table_name, ordinal_position

        set @vcStrColumns = @vcStrColumns + @vPrefixTbName + 'tipo_operazione char(1),' + char(13)
        set @vcStrColumns = @vcStrColumns + @vPrefixTbName + 'data_last_modify datetime,' + char(13)
        set @vcStrColumns = @vcStrColumns + @vPrefixTbName + 'oper_name_last_modify varchar(50)' + char(13)
       
        set @vcRetStrSql = @vcStrPre + @vcStrColumns + ') on TRACE'

        return @vcRetStrSql
    End
    GO

    SET ANSI_NULLS OFF
    GO
    SET QUOTED_IDENTIFIER OFF
    GO

     

    Conta che le variabili sono state separate per una questione di leggibilità ma non c'era un particolare bisogno, il risultato non cambia se si utilizza un'unica variabile varchar(8000). La tabella dove ho avuto problemi presenta 105 campi.

    Ciao

    Marco 

    Filed under: ,
    • Post Points: 20
  • 01-23-2008 10.15 In reply to

    • lbenaglia
    • Top 25 Contributor
      Male
    • Joined on 05-14-2007
    • Vimercate (Milano)
    • Posts 79
    • Points 1.170

    Re: Problema su variabili dichiarate varchar(8000)

    Keylog:
    select @vcStrColumns = @vcStrColumns + column_name + '_trac '

    In questa riga concateni alla variabile locale @vcStrColumns definita come varchar(6000) la colonna column_name dell'information schema COLUMNS definita come nvarchar(128).

    Dato che nvarchar ha precedenza superiore rispetto a varchar, il tutto verrà implicitamente convertito a nvarchar, quindi con una lunghezza massima di 4000 caratteri unicode.

    Probabilmente puoi risolvere eseguendo un cast esplicito a varchar di tutte le variabili/colonne nvarchar che vuoi concatenare.

    Ciao!

    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://italy.mvps.org
    • Post Points: 20
  • 01-23-2008 12.45 In reply to

    • Keylog
    • Top 50 Contributor
    • Joined on 06-04-2007
    • Posts 13
    • Points 215

    Re: Problema su variabili dichiarate varchar(8000)

    Grazie 1000 Lorenzo era come dicevi tu! Le colonne column_name e data_type sono nvarchar(128) e questo causava il troncamento per via della precedenza; non me ne ero mai accorto.

    Grazie ancora e a presto

    Marco 

    • Post Points: 5
Page 1 of 1 (9 items)
(C) 2007 User Group Italiano di SQL Server