Funções que ajudam no SQL

Forum sobre SQL.

Moderador: Moderadores

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

Funções que ajudam no SQL

Mensagem por JoséQuintas »

Não tem a ver diretamente com SQL, mas ajuda.
Conforme a gente vai tendo situações semelhantes, a gente cria funções para facilitar.

Por exemplo: vai criar a query com campos data, numérico, caractere, etc.

Código: Selecionar todos

cSql := Ltrim( Str( nNumero ) )
cSql := ['] + Transform( Dtos( Date() ), "@R 9999-99-99" ) + ['] 
cSql := ['] + cString + [']
Não apenas SQL, poderia ser XML, Json, etc.
Uma função auxiliar facilita.

Código: Selecionar todos

FUNCTION ValueSQL( xValue )
DO CASE
CASE xValue == Nil
   RETURN "NULL"
CASE ValType( xValue ) == "N"
   RETURN Ltrim( Str( xValue ) )
CASE ValType( xValue ) == "D"
   RETURN ['] + Transform( Dtos( xValue ), "@R 9999-99-99" ) + [']
ENDCASE
RETURN ['] + Transform( xValue ) + [']
Ou poderia ser NumberSQL( nNumero ), DateSQL( nNumero ), StringSQL( nNumero )

Depois nos fontes só usar:

Código: Selecionar todos

cSql := ValueSql( xValor )
A vantagem do NumberSQL(), StringSQL() seria poder definir o tipo desejado, independente do conteúdo.
Gravar "1" como numérico ou string, por exemplo.
Isto pode ser útil em migrações, que foi o que eu usei: no MySQL pode gravar "000001" em um campo numérico ou string.
Isso permite mudar a base de dados de caractere para numérica, sem precisar mexer nos fontes depois.

Uma outra que criei:

Código: Selecionar todos

FUNCTION ArrayAsSQL( aList )

   LOCAL cTxt := "", oItem

   FOR EACH oItem IN aList
      IF oItem:__EnumIndex != 1
         cTxt += ", "
      ENDIF
      cTxt += ValueSQL( oItem )
   NEXT

   RETURN cTxt
Isso acima permitiria passar um array { 1, 2, 3 } para a função e ela retornar "1,2,3" pra ser usado no SQL, por exemplo em um IN ( 1,2,3 )
Tanto faz se é data, string, valor, ou tudo misturado.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Funções que ajudam no SQL

Mensagem por JoséQuintas »

Outro exemplo: em muitas situações só precisa um único campo.
Pra que encher de comandos SQL pra isso em tudo que é fonte.

Código: Selecionar todos

ValueFromSql( "NOME", "C", "CADASTRO", "IDCADASTRO=10" )
Acabei usando do jeito acima.
A função consulta na tabela CADASTRO, onde o IDCADASTRO=10, e retorna NOME, no formato Caractere.
Se tiver NULL, equivalente a Nil, mesmo assim vai retornar string, uma string vazia, é isso que a função faz.

Não muito diferente de DBF:
Você também poderia ter a função pra fazer o SEEK 10 no cadastro, e mostrar o cadastro->Nome.

Então, não é que SQL dá mais trabalho.
É que já temos várias funções prontas pra trabalhar com DBF.
Quando o SQL está no começo, ainda precisamos começar a montar nossa biblioteca conforme a necessidade.
Mas nem sequer sabemos ainda qual a nossa necessidade.

Começamos do jeito mais trabalhoso, mas devemos prestar atenção no que pode facilitar, pra começar a criar nossa lib pra SQL.
Quanto mais usar/facilitar, tudo vai ficar cada vez mais prático.
Primeiro é funcionar, e depois é começar a facilitar, porque só depois de começar e funcionar, é que vamos enxergar o que poderia facilitar.

Também por isso é bom fazer devagar, quando tudo está bem.
Se for tudo pra ontem, não vai dar tempo de facilitar, e pode complicar fontes cada vez mais, sem perceber.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Funções que ajudam no SQL

Mensagem por JoséQuintas »

Dois exemplos do que mencionei usando junto com minha classe de ADO:

Código: Selecionar todos

FUNCTION ADORecCount( cTable, cWhere, cnSQL )

   LOCAL nValue

   IF cnSQL == NIL
      cnSQL := ADOClass():New( AppConexao() )
   ENDIF
   WITH OBJECT cnSQL
      :cSQL := "SELECT COUNT(*) AS QTD FROM " + cTable + iif( cWhere == Nil .OR. Empty( cWhere ), "", " WHERE " + cWhere )
      :Execute()
      nValue := :Number( "QTD" )
      :CloseRecordset()
   ENDWITH

   RETURN nValue

FUNCTION ADOField( cField, cType, cTable, cWhere, cnSQL )

   LOCAL xResult

   IF cnSQL == NIL
      cnSQL := ADOClass():New( AppConexao() )
   ENDIF
   WITH OBJECT cnSQL
      :cSQL := "SELECT " + cField + " FROM " + cTable + iif( cWhere == Nil .OR. Empty( cWhere ), "", " WHERE " + cWhere )
      :Execute()
      DO CASE
      CASE cType == "N" ; xResult := :Number( cField )
      CASE cType == "D" ; xResult := :Date( cField )
      OTHERWISE         ; xResult := :String( cField )
      ENDCASE
      :CloseRecordset()
   ENDWITH

   RETURN xResult
Quero saber quantos registros tem em clientes, nem precisa saber o que está sendo usado:

Código: Selecionar todos

? ADORecCount( "clientes" )
Quero saber quantos clientes tem em SP:

Código: Selecionar todos

? ADORecCount( "clientes", "CLIUF='SP'" )
Quero o nome do cliente de código 10

Código: Selecionar todos

? ADOField( "NOME", "C", "CLIENTE", "IDCLIENTE=10" )
Não precisa conexão, recordset, comando SQL, nada disso.
Como é algo comum, que acaba sempre precisando em algum lugar do aplicativo, só criar uma função genérica e pronto.

Nem só de SQL vive o aplicativo, mesmo que tudo seja através de comandos SQL.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Funções que ajudam no SQL

Mensagem por JoséQuintas »

Aí alguém vai dizer..... mas usando LIB tal, faz tudo automático.
Ou até mesmo: usando recursos do ADO não precisa nem comandos SQL....

Ué...
Se podemos criar nossa própria LIB pra isso, do jeito que a gente precisar.... direcionada para nosso uso/estilo....
Porque ficar preso a LIB de alguém, se podemos depender somente de nós?
E fazer tudo de nosso jeito.
Se tudo mudar, vai ser só mudar nossas LIBs e pronto.
Se o ADO deixar de existir, é só ajustar as LIBs, não dependo do ADO pra isso, basta a função ser alterada pra não usar mais ADO.

E por isso é bom ficar nos comandos SQL, e funções pra facilitar, assim não depende de LIB nenhuma, nem do ADO Microsoft.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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/
Responder