Modifica da tipo image a varbinary

di il
6 risposte

Modifica da tipo image a varbinary

Ciao a tutti.

Tra poco, dice Microsoft, i tipi di dati image non saranno più gestiti. Al loro posto usare varbinary. Mi trovo a dover modificare delle store procedure ereditate che lavorano su campi di tipo image.

Dovrei convertirle per l'uso con varbinary.  Si tratta di SP che gestiscono file immagine il cui nome è ricevuto da programma.

La table, è impostata così:

CREATE TABLE [dbo].[blobs] (
[blob] [decimal](11, 0) IDENTITY (1, 1) NOT NULL ,
[name] [char] (30) NOT NULL ,
[size] [int]  NULL,
[file] [image]  NULL ,
[id_row] [timestamp] NOT NULL

) ON [PRIMARY]

le store procedure sono più di una, ma quelle più problematiche sono quelle in cui si usa TEXTPTR e UPDATETEXT che andranno convertite per l'uso con la colonna file di tipo varbinary. 

Sono in difficoltà, lo ammetto. Qualcuno ha voglia di darmi un suggerimento?

Grazie in anticipo.

--------

Gigi

--------

CREATE PROCEDURE cp_blob_temp 

AS
 DECLARE @TimeStr varchar(30), @INDEX INT, @CHAR CHAR(1)
SET @TIMESTR = convert(varchar(30),GETDATE(),20)
       SET @INDEX = 1
       WHILE @INDEX <= LEN(@TIMESTR)
        BEGIN
         SET @CHAR = SUBSTRING(@TIMESTR,@INDEX,1)
  IF (ASCII(@CHAR)< 48) or (ASCII(@CHAR)> 57)
            SET @TIMESTR = STUFF(@TIMESTR,@INDEX,1,'_')
  SET @INDEX = @INDEX +1
    END
       
EXEC ('CREATE TABLE blob_temp'+@TimeStr+' (
 [blob] decimal(11,0),
 [SIZE] int,
 [NAME] varchar(50),
 [FILE] Image,
 [POS] int)')

Exec('CREATE TRIGGER insertImage'+@TIMESTR+' 
ON blob_temp'+@TIMEstr+'
FOR  INSERT
AS 
BEGIN
  DECLARE @ptrval binary(16), @SIZE int, @NAME varchar(40),@blob  decimal(11,0)
  DECLARE @ptrval1 varbinary(16), @INS decimal(2,0),@poz int
  SELECT @ptrval1 = TEXTPTR([file]), @blob = blob, @poz = POS
      FROM blob_temp'+@TIMESTR+'

SELECT @ptrval = TEXTPTR([FILE]) 
  FROM blobs WHERE blob = @blob 
if @poz =0

   UPDATETEXT [blobs].[FILE] @ptrval 0 NULL  [blob_temp'+@TIMESTR+'].[FILE]  @ptrval1
 
else

  UPDATETEXT [blobs].[FILE] @ptrval null NULL  [blob_temp'+@TIMESTR+'].[FILE]  @ptrval1

delete from blob_temp'+@TIMESTR+' where blob = @blob
END')

select 'blob_temp'+@TIMESTR

GO

CREATE PROCEDURE cp_chunkSet 
@BLOB decimal(11,0),
@ROZ int
AS
DECLARE @PTRVAL1 varbinary(16),  @POZ int,  @INDEX int,  @RESZTA int
BEGIN TRANSACTION
SELECT @PTRVAL1 = TEXTPTR([FILE]) 
 FROM blobs WHERE blob = @BLOB  
SET @POZ = 0
IF (@ROZ >512000)
   SET @INDEX = 512000
ELSE
   SET @INDEX = @ROZ
 SET @RESZTA = @ROZ
WHILE (@INDEX <= @ROZ)
 BEGIN
  IF @INDEX = @ROZ
     BEGIN 
          READTEXT [blobs].[FILE] @PTRVAL1 @POZ @RESZTA
          SET @INDEX  =@INDEX +100
      END
  ELSE
     BEGIN
    READTEXT [blobs].[FILE] @PTRVAL1 @POZ 512000
    SET @POZ = @INDEX
    SET @INDEX = @INDEX +512000
         IF @INDEX > @ROZ
            BEGIN
      SET @RESZTA = 512000 - (@INDEX - @ROZ)
      SET @INDEX = @ROZ 
            END
       END
 END
COMMIT TRANSACTION

6 Risposte

  • Re: Modifica da tipo image a varbinary

    Probabilmente puoi fare una cosa MOOOOLT piu' “stupida”/"semplice":

    ti definisci un tipo custom con nome “image” che non e' altro che un alias per “varbinary”.

    Fai qualche prova

  • Re: Modifica da tipo image a varbinary

    Ciao.

    Si ma dopo TEXTPTR([FILE])  funzionerà-? non funziona con i tipi varbinary.

  • Re: Modifica da tipo image a varbinary

    Premetto che non ho mai usato la funzione TEXTPTR, ma leggendo la documentazione di Microsoft

    (https://learn.microsoft.com/en-us/sql/t-sql/functions/text-and-image-functions-textptr-transact-sql?view=sql-server-ver16)

    vedo scritto:

    Returns the text-pointer value that corresponds to a text, ntext, or image column in varbinary format. The retrieved text pointer value can be used in READTEXT, WRITETEXT, and UPDATETEXT statements.

    Quindi, quella funzione restituisce già ora un tipo varbinary.

  • Re: Modifica da tipo image a varbinary

    Ho letto anch'io la documentazinoe microsoft e credo che non ci siamo. Ritorna un puntatore ad una colonna di testo in formato varbinary nella variabile ptrval1, che viene usata poi per maneggiare il contenuto della colonna file che è di tipo image.

    volevo solo sapere, visto che queste funzioni sono deprecate, come adeguare le store procedure alle nuove versioni di sqlserver, non usando queste due funzioni textptr e readtext e updatetext.

    Grazie comunque.

  • Re: Modifica da tipo image a varbinary

    Salve,

    il tipo varbinary permette operazioni “semplici” e tradizionali sul tipo di dato della colonna, quindi tranquillamente
    SELECT colVarBinary FROM tbl;

    UPDATE tbl SET colVarBinary  = @paramVarBinary WHERE id = n;

    etc… non servono piu' TEXPTR, READTEXT etc per operare sulla colonna… chiaro che il codice e i parametri vanno modificati, ma tutto diventa piu' semplice, molto piu' semplice…

    la tabella puo' essere “aggiornata” direttamente con un alter table, vedi ad esempio https://stackoverflow.com/questions/31541241/convert-table-column-data-type-from-image-to-varbinary

    tutti quegli arzigogoli precedenti per recuperare il pointer al valore della colonna spariscono… le assegnazioni diventano “standard”… alla sp di inserimento/aggiornamento passi i parametri e li usi “semplicemente”…

    trivialmente, qualche cosa di simile a 

    CREATE PROC dbo.usp_TABELLA_U (
    	@Id int,
    	--....
    	@File varbinary(MAX)
    ) AS BEGIN
    
    	SET NOCOUNT ON;
    	DECLARE @r int;
    	DECLARE @msg varchar(1000);
    	DECLARE @task varchar(15);
    	DECLARE @Key varchar(15);
    
    	BEGIN TRY
    		IF @@TRANCOUNT = 0	BEGIN
    			SET @msg = CAST(OBJECT_NAME(@@PROCID) AS sysname)
    			RAISERROR ('L''esecuzione della procedura [%s] e'' subordinata all''inserimento in una transazione.', 16, 1, @msg);
    			END;
    
    		SET @task = 'Aggiornare';
    		
    		SET NOCOUNT OFF;
    		UPDATE dbo.TABELLA
    			SET colVarBinary = @File
    			--, ....
    			WHERE Id = @Id;
    
    		SET @r = @@ROWCOUNT;
    
    
    
    		SET NOCOUNT ON;
    
    		IF (@r = 0) BEGIN			
    			-- in caso di non aggiornamento righe notifica la
    			-- possibile violazione di concorreza e necessita di refresh
    			SET @msg = 'Impossibile %s riga con chiave = [%s] in  [%s].' + CHAR(10) + 'Possibile conflitto di concorrenza.';
    			RAISERROR (@msg, 16, 1, @task, @Key , 'tabella XYZ');
    			END;
    
    		RETURN 0;
    
    	END TRY
    
    	BEGIN CATCH
    		-- ritorna l'errore
    		DECLARE @ErrorMSG varchar(2000);
    		SET @ErrorMSG = ERROR_MESSAGE();
    		RAISERROR (@ErrorMSG, 16, 1);
    		RETURN -100;
    	END CATCH
    
    END;
    GO
    

    E' “tutto facile” :D

    salutoni romagnoli
    – 
    Andrea

  • Re: Modifica da tipo image a varbinary

    Ciao Andrea, proprio quelloche cercavo. queste funziooni le ho eredeitate e prima di incasinarmi passando a nuove versioni di sqlserver volevo mettere le mani avanti. mi studiero' la tua risposta con attenzione.

    mille grazie dal veneto.

Devi accedere o registrarti per scrivere nel forum
6 risposte