none
Procedure para INSERIR imagens no banco de dados RRS feed

  • Pergunta

  • Pessoal,

    Estou com a seguinte procedure, porém está com erro...

     

    
    
    DECLARE @caminho AS VARCHAR (200)
    DECLARE @codimagem AS VARCHAR (25)
    DECLARE @sql_update NVARCHAR (1000)
    SELECT @caminho = 'Z:\' +((SELECT DATENAME (year , mat.datamateri))+'\' +(SELECT TOP 1 mes_pt FROM meses WHERE mes = MONTH (datamateri))+'\' +
    (SELECT DATENAME (day , mat.datamateri))+'\' +(cast (img2.codimagem as varchar (200)))+'.jpg' )
    FROM materiaimagem_stf_img2 img2, materia_stf mat WHERE img2.codmateria = mat.codmateria AND img2.codimagem = '1235802'
    SELECT @codimagem = img2.codimagem FROM materiaimagem_stf_img2 img2, materia_stf mat WHERE img2.codmateria = mat.codmateria
    AND img2.codimagem = '1235802'
    SET @sql_update = N'(select * FROM OPENROWSET(BULK ' '' + @caminho + '' ', SINGLE_BLOB)as tt)' --,
    --fname = ''' + @codimagem + ''+'.jpg'
    BEGIN
    UPDATE materiaimagem_stf_img2
    SET [file] = @sql_update,
    fname = @codimagem+'.jpg'
    WHERE materiaimagem_stf_img2.codimagem = @codimagem
    END 

     

    Msg 257, Level 16, State 3, Line 18
    Implicit conversion from data type nvarchar to varbinary(max) is not allowed. Use the CONVERT function to run this query.

    • Editado CarlosHB quarta-feira, 26 de janeiro de 2011 22:09
    quarta-feira, 26 de janeiro de 2011 17:49

Respostas

  • Boa Noite,

    Seu exemplo ainda não está correto. É necessário que a variável @sql_update contemple todo o comando. No seu script, ela contempla apenas o OPENROWSET. É preciso que ele tenha o UPDATE montado para então o EXEC efetuar a execução. Dê uma olhada na parte do meu script anteriormente.

    SET @sql_update = 'UPDATE materiaimagem_stf_img2
    SET [file] = ' + @sql_update + ',
    fname = @codimagem+''.jpg''
    WHERE materiaimagem_stf_img2.codimagem = @codimagem'
    PRINT @sql_update
    EXEC(@sql_update)
    

    Observe que o comando é montado dinamicamente para posterior execução.

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.wordpress.com


    Classifique as respostas. O seu feedback é imprescindível
    • Sugerido como Resposta Gustavo Maia Aguiar terça-feira, 29 de março de 2011 22:15
    • Marcado como Resposta Eder Costa segunda-feira, 4 de abril de 2011 14:41
    terça-feira, 29 de março de 2011 22:15

Todas as Respostas

  • O erro diz que está nesta parte onde passo a variável @sql_update como parâmetro...

    SET @sql_update = N'(select * FROM OPENROWSET(BULK ''' + @caminho + ''', SINGLE_BLOB)as tt)'--, 
    
    
    Que faria a inserção da imagem no banco de dados...

    quarta-feira, 26 de janeiro de 2011 17:52
  • tentei esta conversão e também não deu certo...

    SELECT CAST(CAST(@sql_update AS varbinary(20)) AS NVARCHAR(1000))
    

    quarta-feira, 26 de janeiro de 2011 18:27
  • CarlosHB,

    Antes de tentar ficar dando tiros no escuro, você poderia explicar o que este script deveria fazer?


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]
    quarta-feira, 26 de janeiro de 2011 18:42
  • Ok, desculpe...acabei jogando e não expliquei realmente...

    Estou tentando montar uma procedure para inserir o caminho (onde está as imagens) concatenado com os código das imagens, para posteriormente passar como parâmetro no UPDATE...

    Porque preciso inserir mais de 1000 imagens no database, só que estou precisando automatizar isto...

    Na variável

    @sql_update

    eu passo a query para inserir imagens concatenando com o caminho e o código.

    N'(select * FROM OPENROWSET(BULK ''' + @caminho + ''', SINGLE_BLOB)as tt)'

    • Editado CarlosHB quarta-feira, 26 de janeiro de 2011 18:56
    quarta-feira, 26 de janeiro de 2011 18:51
  • CarlosHB,

    Você deseja inserir o caminho físico da imagem?

    De que forma este caminho seria capturado, ou seja, como você pensar em informar este caminho para esta quantidade de arquivos?

    Todas as imagens estão no mesmo local? O código da imagem seria concatenado com o caminho do arquivo?

    Este código seria por acaso o ID da figura?


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]
    quarta-feira, 26 de janeiro de 2011 18:55
  • Isto o caminho físico onde se localiza a imagem para eu passar como parâmetro na procedure e inserir as (diversas) imagens direto...por exemplo

    W:\2010\Novembro\4

    Dai concateno com a barra mais o código da imagem ficando desta forma:

    W:\2010\NOVEMBRO\5\158450.jpg

    Esta é a variável @caminho.

    Todas as imagens estão no mesmo local...sempre mudando apenas as pastas com o ano, mês e dia....

    O código concatenado na verdade pode se considerar um ID, é o código da imagem

    abaixo a variável @codimagem

    158450

     

     

    quarta-feira, 26 de janeiro de 2011 19:02
  • Será que alguém tem alguma idéia de como eu posso fazer essa atualização?

    Valeu!

    quarta-feira, 26 de janeiro de 2011 21:35
  • Boa Noite,

    Sua implementação está errada. Veja que a coluna "file" é um VARBINARY e você está tentando atualizar essa coluna com uma variável @sql_update que é um NVARCHAR. É natural que o erro ocorra já que não é possível converter essa coluna.

    Já imagino que você irá questionar: Mas o conteúdo da variável é para fazer referência a um caminho e trazer o BLOB do arquivo.
    Sim eu entendo sua idéia, mas o fato é que a variável é um NVARCHAR e não fará diferença se ela é um comando de SELECT ou se ela é um texto do tipo "XXXXX". Independente do seu conteúdo, ela continuará sendo um NVARCHAR e o erro persistirá.

    Para fazer sua implementação você deverá utilizar uma SQL dinâmica e englobar todo o UPDATE. Ex:

    DECLARE @caminho AS VARCHAR (200)
    DECLARE @codimagem AS VARCHAR (25)
    DECLARE @sql_update NVARCHAR (1000)
    SELECT @caminho = 'Z:\' +((SELECT DATENAME (year , mat.datamateri))+'\' +(SELECT TOP 1 mes_pt FROM meses WHERE mes = MONTH (datamateri))+'\' +
    (SELECT DATENAME (day , mat.datamateri))+'\' +(cast (img2.codimagem as varchar (200)))+'.jpg' )
    FROM materiaimagem_stf_img2 img2, materia_stf mat WHERE img2.codmateria = mat.codmateria AND img2.codimagem = '1235802'
    SELECT @codimagem = img2.codimagem FROM materiaimagem_stf_img2 img2, materia_stf mat WHERE img2.codmateria = mat.codmateria
    AND img2.codimagem = '1235802'
    SET @sql_update = N'(select * FROM OPENROWSET(BULK ''' + @caminho + ''', SINGLE_BLOB)as tt)' --,
    --fname = ''' + @codimagem + ''+'.jpg'
    BEGIN
    SET @sql_update = 'UPDATE materiaimagem_stf_img2
    SET [file] = ' + @sql_update + ',
    fname = @codimagem+''.jpg''
    WHERE materiaimagem_stf_img2.codimagem = @codimagem'
    PRINT @sql_update
    EXEC(@sql_update)
    END
    

    Essa não é uma característica das imagens, mas sim da concatenação e execução do código

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.wordpress.com/

    Exclusões em cascata e auto-referência no SQL Server
    http://gustavomaiaaguiar.wordpress.com/2011/01/22/excluses-em-cascata-e-auto-referncia-no-sql-server/


    Classifique as respostas. O seu feedback é imprescindível
    quinta-feira, 27 de janeiro de 2011 03:07
  • Entendi seus esclarecimentos...a variável @sql_update é NVARCHAR mesmo, porém eu não entendia o erro porque eu passava ela como referência com o @caminho para inserir as imagens no banco... 

    Muito Obrigado Gustavo vou testar e te dou um retorno!

    quinta-feira, 27 de janeiro de 2011 13:06
  • Olá CarlosHB!

    houve algum progresso?

    Caso esteja solucionado, marque como resposta o exemplo sugerido pelo Gustavo.

    Att;


    Eder Costa - LATAM Forum Support Engineer
    Microsoft Corporation
    terça-feira, 1 de fevereiro de 2011 17:24
  • Bom dia,

    Infelizmente fiz diversos ajustes na procedure e não deu certo...

    Sempre que rodo a procedure ele insere o caminho da imagem no campo [file] onde deveria ser armazenada a imagem, ainda estou me batendo com isto.

    Obrigado.

    quarta-feira, 2 de fevereiro de 2011 11:23
  • Alguém tem alguma sugestão para me ajudar com esta procedure?

    Obrigado!

    quinta-feira, 24 de março de 2011 16:48
  • Oi Carlos,

    Dê um PRINT no código dinâmico e verifique se ele foi montado corretamente.
    Faça os ajustes até que o comando seja montado corretamente.

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.wordpress.com 


    Classifique as respostas. O seu feedback é imprescindível
    quinta-feira, 24 de março de 2011 20:20
  • Fiz alguns ajustes na minha procedure, agora estou tentando algo com Cursor, porém ainda não consegui...segue o código...

    Em vez de inserir a imagem, ele insere o caminho que eu concatenei no campo VARBINARY que seria para inserir a imagem.

     

    	DECLARE @caminho AS VARCHAR(200)
    	DECLARE @codimagem AS VARCHAR(25)
    	DECLARE @sql_update NVARCHAR(1000)
    	Declare @teste VARCHAR(1000)
    	DECLARE @CursorID int
    	DECLARE Consulta_Cursor CURSOR FOR
    	Select codimagem from materiaimagem_stf_img where [file] is NULL
    	OPEN Consulta_Cursor
    
    FETCH NEXT FROM Consulta_Cursor INTO @CursorID
    WHILE @@FETCH_STATUS = 0
    BEGIN
    		----SET @caminho = (SELECT 'Z:\'+((SELECT DATENAME(year, materia_stf.datamateri))+'\'+(
    		----	SELECT TOP 1 mes_pt 
    		----		FROM meses 
    		----		WHERE mes = MONTH(datamateri))+'\'+
    		----  (SELECT DATENAME(day, materia_stf.datamateri))+'\'+(cast (materiaimagem_stf_img.codimagem as varchar (200)))+'.jpg')
    		----		FROM materiaimagem_stf_img , materia_stf 
    		----		WHERE materiaimagem_stf_img.codmateria = materia_stf.codmateria 
    		----		AND materiaimagem_stf_img.codimagem = @CursorID)
    
    			SELECT @codimagem = img.codimagem 
    				FROM materiaimagem_stf_img img, materia_stf 
    				WHERE img.codmateria = materia_stf.codmateria
    				AND img.codimagem = @CursorID
    				
    				---SET @sql_update = (select * FROM OPENROWSET(BULK @caminho, SINGLE_BLOB)as tt)					
    				--select 	@sql_update
    				--select CAST(@sql_update AS VARBINARY(MAX))
    				
    				----select @sql_update = (select * FROM OPENROWSET(BULK N'" + @caminho + "', SINGLE_BLOB)as tt)
    				select @caminho, @sql_update
     
    			-------							
    		 --SET @sql_str = 'SELECT COUNT(valor) AS valor FROM midia.materia_stf where codmateria WHERE valor= ''' + @ID + ''''
    		 --SET @sql_str = N'select * from OPENQUERY(servidor, ''' + REPLACE(@sql_str, '''', '''''') + ''')'
    		 --SET @sql_update = N'(select * FROM OPENROWSET(BULK ''' + @caminho + '''AS varbinary(max), SINGLE_BLOB)as tt)'--, 
    			
    			--UPDATE materiaimagem_stf_img
    			--SET [file] = CAST(@sql_update AS VARBINARY(MAX)) ,
    			--fname = cast(@CursorID as varchar (200))+'.jpg'
    			--WHERE materiaimagem_stf_img.codimagem = @CursorID			
    						
    FETCH NEXT FROM Consulta_Cursor INTO @CursorID
    
    	--- Execute [sp_selecao_STF_Insere_Imagem]
    
    END
    
    CLOSE Consulta_Cursor
    DEALLOCATE Consulta_Cursor
    

    sexta-feira, 25 de março de 2011 13:02
  • Bom Dia,

    Enquanto não houver o EXEC(@sql_update) você não terá êxito.
    Sugiro rever o exemplo anterior

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.wordpress.com


    Classifique as respostas. O seu feedback é imprescindível
    sexta-feira, 25 de março de 2011 13:18
  • Entendi, mais utilizando está forma com o EXEC(@sql_update) eu consigo utilizar o CURSOR ainda?

    Porque o Cursor está sendo usado para passar como parâmetro o caminho e o código da imagem.

    terça-feira, 29 de março de 2011 14:22
  • Boa Tarde,

    Sim. É possível utilizá-lo com cursor. Para cada iteração monte um comando EXEC e execute-o.

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.wordpress.com


    Classifique as respostas. O seu feedback é imprescindível
    terça-feira, 29 de março de 2011 17:02
  • Obrigado pela ajuda Gustavo...

    Adicionei um cursor na procedure, e inseri o EXEC o final, porém não me retorna nada...tem alguma idéia do que pode ser?

    Dei print nas variáveis, mais não está retornando dados...mais os dados existem nas tabelas...

     

    	DECLARE @caminho AS VARCHAR(200)
    	DECLARE @codimagem AS VARCHAR(25)
    	DECLARE @sql_update NVARCHAR(1000)
    	Declare @teste VARCHAR(1000)
    	DECLARE @CursorID int
    	DECLARE Consulta_Cursor CURSOR FOR
    	SELECT codimagem from materiaimagem_stf_img where [file] is NULL
    	OPEN Consulta_Cursor
    
    FETCH NEXT FROM Consulta_Cursor INTO @CursorID
    WHILE @@FETCH_STATUS = 0
    BEGIN
    		SET @caminho = (SELECT 'Z:\'+((SELECT DATENAME(year, materia_stf.datamateri))+'\'+(
    			SELECT TOP 1 mes_pt 
    				FROM meses WHERE mes = MONTH(datamateri))+'\'+
    		  (SELECT DATENAME(day, materia_stf.datamateri))+'\'+(cast (materiaimagem_stf_img.codimagem as varchar (200)))+'.jpg')
    				FROM materiaimagem_stf_img , materia_stf 
    				WHERE materiaimagem_stf_img.codmateria = materia_stf.codmateria 
    				AND materiaimagem_stf_img.codimagem = @CursorID)
    
    			SELECT @codimagem = img.codimagem 
    				FROM materiaimagem_stf_img img, materia_stf 
    				WHERE img.codmateria = materia_stf.codmateria
    				AND img.codimagem = @CursorID
    				
    				---SET @sql_update = (select * FROM OPENROWSET(BULK @caminho, SINGLE_BLOB)as tt)					
    				--select 	@sql_update
    				--select CAST(@sql_update AS VARBINARY(MAX))
    				
    				SET @sql_update = N'(select * FROM OPENROWSET(BULK ''' + @caminho + ''', SINGLE_BLOB)as tt)' --,
    				
    				SELECT @caminho, @sql_update, @codimagem
     
    			-------							
    		 --SET @sql_str = 'SELECT COUNT(valor) AS valor FROM midia.materia_stf where codmateria WHERE valor= ''' + @ID + ''''
    		 --SET @sql_str = N'select * from OPENQUERY(servidor, ''' + REPLACE(@sql_str, '''', '''''') + ''')'
    		 --SET @sql_update = N'(select * FROM OPENROWSET(BULK ''' + @caminho + '''AS varbinary(max), SINGLE_BLOB)as tt)'--, 
    			
    			UPDATE materiaimagem_stf_img
    			SET [file] = CAST(@sql_update AS VARBINARY(MAX)),
    			fname = cast(@CursorID as varchar (200))+'.jpg'
    			WHERE materiaimagem_stf_img.codimagem = @CursorID			
    					
    			PRINT @sql_update
    			EXEC(@sql_update)	
    
    FETCH NEXT FROM Consulta_Cursor INTO @CursorID
    
    	--- Execute [sp_selecao_STF_Insere_Imagem]
    END
    
    CLOSE Consulta_Cursor
    DEALLOCATE Consulta_Cursor
    
    
    <br/>
    

    terça-feira, 29 de março de 2011 18:07
  • Boa Noite,

    Seu exemplo ainda não está correto. É necessário que a variável @sql_update contemple todo o comando. No seu script, ela contempla apenas o OPENROWSET. É preciso que ele tenha o UPDATE montado para então o EXEC efetuar a execução. Dê uma olhada na parte do meu script anteriormente.

    SET @sql_update = 'UPDATE materiaimagem_stf_img2
    SET [file] = ' + @sql_update + ',
    fname = @codimagem+''.jpg''
    WHERE materiaimagem_stf_img2.codimagem = @codimagem'
    PRINT @sql_update
    EXEC(@sql_update)
    

    Observe que o comando é montado dinamicamente para posterior execução.

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.wordpress.com


    Classifique as respostas. O seu feedback é imprescindível
    • Sugerido como Resposta Gustavo Maia Aguiar terça-feira, 29 de março de 2011 22:15
    • Marcado como Resposta Eder Costa segunda-feira, 4 de abril de 2011 14:41
    terça-feira, 29 de março de 2011 22:15
  • Entendi, vou tentar montar da forma que você passou...

    Muito obrigado pela ajuda!

    quarta-feira, 13 de abril de 2011 00:29