INSERT campo a campo

Forum sobre SQL.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20415
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

INSERT campo a campo

Mensagem por JoséQuintas »

No MySQL, existe algum equivalente ao insert com campo a campo igual update?

Código: Selecionar todos

INSERT INTO TABELA (a, b, c, d, e, f, g, h ) VALUES ( 1, 2, 3, 4, 5, 6, 7, 8 )

Código: Selecionar todos

UPDATE TABELA SET a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8
Quando a lista é grande, corre-se o risco de errar a equivalência.
E apesar do ADO ter recurso pra isso, prefiro comando SQL.

Por enquanto minha saída foi criar um construtor de comandos SQL.
Algo parecido com isto

Código: Selecionar todos

oSqlInsert := SqlInsertClass():New( "tabela" )
oSqlInsert:AddFIeld( "campo1", valor1 )
oSqlInsert:AddFIeld( "campo2", valor2 )
? oSqlInsert:ToString()
Pelo menos fica visível o que está gravando em cada campo.
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 565
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

INSERT campo a campo

Mensagem por Poka »

Olá Quintas

Fiz uma rotina de inclusão e alteração que funciona bem com firebird, estou passando a de inclusão, de repente se for útil para alguma coisa.
Declarar tudo em lista de campos e lista de valores, sem chance, tenho arquivo de nota fiscal por exemplo com "trocentos" campos.

Código: Selecionar todos

*---------------------
mx:={}
vcodigo:=120
vnome:="Roberto"
vsalario:=3000.50
vtexto:="texto"
//
aadd(mx,"codigo","n" ,vcodigo)
aadd(mx,"nome","c" ,vnome)
aadd(mx,"salario","n" ,vsalario)
aadd(mx,"texto","m" ,vtexto)
if empty(xmen:=fb_insert("funcionario",mx) )
   msginfo("Ok")
else   
			msginfo(xmen)
endif
retu nil
*-------------------------------------
func fb_Insert(xxarq,xMx)
   // mx é uma matriz que contem nome do campo , tipo e conteudo 
   // xarq é a tabela 
   local _men:=""  ,a,x  , xqtdecimal:=0
			priva xarq:=xxarq , xcampo, xconteudo:="" , xtipo:="" ,	 mx:=xmx
			listaCampos:=""
			ListaConteudo:=""
			for a:= 1 to len(mx)
 			  xcampo:=mx[a,1]
	 		  xtipo:=upper(mx[a,2] )
	 		  xconteudo:=mx[a,3]
	 		  if xtipo $ "CM"
          xconteudo:=strTran(xconteudo,"'","´") 
      endif    
	 		  IF xtipo="C"
	 		     xconteudo:=strtran(xconteudo,"'","´")
   	 		  ListaCampos+=xcampo
	 	   	  listaConteudo+="'"+xconteudo+"'"
	 		  elseIF xtipo="D"
	 		     ListaCampos+=xcampo
									if empty( xconteudo)
   	 		     xconteudo:="0001-01-01"
									else
   	 		     xconteudo:=strzero(year(xconteudo) ,4)+"-"+ strzero(month(xconteudo),2)+"-"+strzero(day(xconteudo),2)
									endif   
   	 		  ListaConteudo+="'"+xconteudo+"'"
	 		  elseIF xtipo="N"
   	 		  ListaCampos+=xcampo
									xqtdecimal:=qtDecimal(xconteudo)
	 	   	  listaConteudo+="'"+ alltrim( str(xconteudo,14,xqtdecimal))   +"'"
	 		  elseIF xtipo="M"
   	 		  ListaCampos+=xcampo
	 	   	  listaConteudo+="'"+xconteudo+"'"
	 	   endif	  
	     if a < len(mx)
   	 		  ListaCampos+=+","
	     	  listaConteudo+=","
	     endif	  
	 	next	  
			Str:="insert into "+xarq+" ("+listaCampos+") values (" + listaconteudo+");"
			_men:=Fb_executa()
			*--------------
			release xarq , xcampo  , xconteudo, xtipo
retu _men
*----------------------------------------------
func Fb_executa
			// se retornar mensagem em branco, deu certo 
			local _men:="" , xConexao:="oConnection"
  	&(xConexao):Setsql( Str )
   if ! &(xConexao):open()
			   _men:= &(xconexao):SQLErrorMessage()
			endif   
   if empty( _men)
      // deu certo
      M_select:=&(xconexao):aRecordSet   // matriz ja declarada como publica anteriormente
      // na rotina que chama pode testar m_select, se vazia ou nao
   else
			   m_select:={}  
			endif
retu _men	 	
*-----------------
func qtDecimal(xnum)
   // retorna a qt de casas decimais de um numero 
			local xqt:=0
   xnum:= alltrim(str(xnum - int(xnum) )) 
   xqt:=len(alltrim(substr( xnum,3,20) ) )
retu (xqt)

Poka
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20415
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

INSERT campo a campo

Mensagem por JoséQuintas »

Acabou fazendo praticamente a mesma coisa, e poderia até reduzir aproveitando minha rotina.

Dá certo isso no Add() ?

Código: Selecionar todos

AAdd( mx, "codigo", "n", vCodigo )
Eu uso o própio tipo da variável pra conversão, o array fica só com nome e conteúdo.

Código: Selecionar todos

METHOD ToString( cTable ) Class SqlInsertClass

   LOCAL cSql, oField, nCont := 1

   cSql := "INSERT INTO " + cTable + " ( "
   FOR EACH oField IN ::aFields
      cSql += oField[ 1 ] + iif( nCont == Len( ::aFields ), "", ", " )
      nCont += 1
   NEXT
   cSql += " ) VALUES ( "
   nCont := 1
   FOR EACH oField in ::aFields
      cSql += ValueSql( oField[ 2 ] ) + iif( nCont == Len( ::aFields ), "", ", " )
      nCont += 1
   NEXT
   cSql += " )"
   RETURN cSql


FUNCTION ValueSql( xCampo )
   IF ValType( xCampo ) == "D"
      IF Empty( xCampo )
          RETURN "NULL"
      ELSE
          RETURN ['] + Transform( Dtos( xCampo ), "@R 9999-99-99" ) + ['] )
      ENDIF
   ENDIF
   RETURN ['] + Transform( xCampo, "" ) + [']
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20415
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

INSERT campo a campo

Mensagem por JoséQuintas »

No Harbour, o Aadd não aceita isso, a não ser que exista hb_Add() com esse recurso a mais.

Código: Selecionar todos

PROCEDURE Main
   LOCAL a := {}
   AAdd( a, nCont, nCont, nCont )
   ? a[ 1, 1 ], a[ 1, 2 ], a[ 1, 3 ]
   RETURN
test.prg(3) Error E0021 Incorrect number of arguments in AADD
Passed: 4, expected: 2
1 error
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
alxsts
Colaborador
Colaborador
Mensagens: 3108
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

INSERT campo a campo

Mensagem por alxsts »

Olá!

Respondendo a questão inicial do tópico: não, não existe. A especificação do SQL ANSI, de onde todos os SGBS derivaram suas especificações próprias, não contempla isto. Já me perguntei isto há alguns anos. Seria bem mais prático mas, não existe.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 565
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

INSERT campo a campo

Mensagem por Poka »

desculpe , errei no escrever o exemplo, o correto é


aadd(mx,{"codigo","n" ,vcodigo})
aadd(mx,{"nome","c" ,vnome})
aadd(mx,{"salario","n" ,vsalario})
aadd(mx,{"texto","m" ,vtexto})

Poka
Responder