Array
(
)

Como fazer o PHP entender função SQL

Maca
   - 12 jun 2015

Prezados, boa tarde!
Como faço para o PHP entender uma função SQL? Por exemplo..
#Código

USE [vetorh_ponto]
GO
/****** Object:  UserDefinedFunction [dbo].[V_RELOGIO_PONTO]    Script Date: 06/12/2015 13:57:52 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[V_RELOGIO_PONTO] (@TIPO CHAR(7))
returns @TABELA table
( CRACHA_1 INT, FUNCIONARIO VARCHAR(40), SETOR VARCHAR(60), DATA_ACESSO DATETIME, HORA_ACESSO time, 
  CATRACA varchar(60), CODIGO_EVENTO smallint, NOME_EVENTO VARCHAR(20), TOTAL INT                   )
AS
BEGIN
	DECLARE @CAFE_INI int, @CAFE_FIM int,
			@ALMOCO_INI int, @ALMOCO_FIM int,
			@JANTAR_INI int, @JANTAR_FIM int,
			@CEIA_INI int, @CEIA_FIM int,
			@INICIO DATETIME, @FIM DATETIME

	SET @CAFE_INI   = (SELECT CAST(cnf_valor as INT) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_CAFE_INI') 
	SET @CAFE_FIM   = (SELECT CAST(cnf_valor as INT) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_CAFE_FIM')
	SET @ALMOCO_INI = (SELECT CAST(cnf_valor as INT) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_ALMOCO_INI')
	SET @ALMOCO_FIM = (SELECT CAST(cnf_valor as INT) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_ALMOCO_FIM')
	SET @JANTAR_INI = (SELECT CAST(cnf_valor as INT) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_JANTAR_INI')
	SET @JANTAR_FIM = (SELECT CAST(cnf_valor as INT) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_JANTAR_FIM')
	SET @CEIA_INI   = (SELECT CAST(cnf_valor as INT) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_CEIA_INI')
	SET @CEIA_FIM   = (SELECT CAST(cnf_valor as INT) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_CEIA_FIM')
	SET @INICIO = (SELECT CAST(cnf_valor AS datetime) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_DATA_INI') 
	SET @FIM    = (SELECT CAST(cnf_valor AS datetime) FROM AIS.APIS.DBO.T_CONFIG WHERE CNF_CAMPO = 'VETOR_DATA_FIM')


if @tipo = 'CAFE'
	INSERT @TABELA ([CRACHA_1],[FUNCIONARIO],[SETOR],[DATA_ACESSO],[HORA_ACESSO],[CATRACA],[CODIGO_EVENTO],[NOME_EVENTO])
	SELECT r038hch.numcad 'CRACHÁ_1', r034fun.nomfun 'FUNCIONARIO',r016orn.nomloc 'SETOR',r070acc.datacc 'DATA_ACESSO', right((convert(char(8), dateadd(second, r070acc.horacc, ''), 114)),5) 'HORA_ACESSO', r058rlg.desrlg 'CATRACA',r070acc.tipacc 'CODIGO_EVENTO',r070tac.desred 'NOME_EVENTO'
	FROM r070acc,r034fun,r070tac,r058rlg,r038hch,r038hlo,r016orn,r030emp WHERE r070acc.codplt = r058rlg.codplt AND r070acc.codrlg = r058rlg.codrlg AND r070tac.tipacc = r070acc.tipacc AND r034fun.numemp = r030emp.numemp AND r038hch.numemp = r030emp.numemp AND r038hlo.numemp = r030emp.numemp AND r038hlo.taborg = r016orn.taborg AND r038hlo.numloc = r016orn.numloc AND
	(r070acc.datacc between @INICIO and @FIM AND r070acc.horacc between @CAFE_INI and @CAFE_FIM)
	AND r038hch.numcra = r070acc.numcra AND (r038hch.datini < r070acc.datacc OR (r038hch.datini = r070acc.datacc AND r038hch.horini <= r070acc.horacc)) AND (r038hch.datfim = CONVERT(DATETIME,'1900/12/31',111) OR r038hch.datfim > r070acc.datacc OR (r038hch.datfim = r070acc.datacc AND r038hch.horfim >= r070acc.horacc)) AND r034fun.numemp = r038hch.numemp AND r034fun.tipcol = r038hch.tipcol AND r034fun.numcad = r038hch.numcad AND r034fun.numemp = r038hlo.numemp AND r034fun.tipcol = r038hlo.tipcol AND r034fun.numcad = r038hlo.numcad AND r038hlo.datalt = (SELECT MAX(datalt) FROM r038hlo a WHERE a.numemp = r034fun.numemp AND a.tipcol = r034fun.tipcol AND a.numcad = r034fun.numcad AND a.datalt <= r070acc.datacc) AND 0 = 0 ORDER BY 1 ASC,2 ASC,4 ASC

Como faço para o PHP entender isso? Preciso separar por partes? Como fazer a variável @CAFE_INI do SQL por exemplo, passar a ser um $_GET da data digitada pelo usuário na minha aplicação PHP?

Wellington Pereira
   - 12 jun 2015

Você terá que conectar o PHP com seu banco de dados e usar funções do php para realizar consultas, inserções e remoções.

Links úteis:

http://php.net/manual/pt_BR/function.mysql-query.php
http://php.net/manual/pt_BR/pdo.query.php
http://php.net/manual/pt_BR/book.mysqli.php

Marcio Araujo
   - 12 jun 2015

Mais um link: http://php.net/manual/pt_BR/ref.mysql.php

Maca
   - 12 jun 2015

Legal pessoal... O PHP já conecta no banco, só não sei trazer os dados dessa função.. No caso como a query é feita com sqlsrv_query, há muitas mudanças? Ou apenas a sintaxe inicial? ex: sqlsrv_query / mysql_query ..

Marcio Araujo
   - 12 jun 2015

Confesso que não entendi a sua ultima pergunta, mas acho que tem relação com essse link: http://ctncardoso.com.br/blog/2011/02/consultas-sql-utilizando-pdo-php-data-objects/

Wellington Pereira
   - 14 jun 2015


Citação:
Legal pessoal... O PHP já conecta no banco, só não sei trazer os dados dessa função.. No caso como a query é feita com sqlsrv_query, há muitas mudanças? Ou apenas a sintaxe inicial? ex: sqlsrv_query / mysql_query ..


Nesse caso a sintaxe será :
#Código

sqlsrv_query


Porém algumas medidas devem ser tomadas antes para conectar o sql server ao php.

Seguem alguns links para lhe auxiliar, tem todas as formas de conexão e manipulação de dados do SQL Server com PHP:
https://www.youtube.com/watch?v=1eudslEMba0
http://wiki.locaweb.com/pt-br/Conectando-se_ao_MS_SQL_Server_atrav%C3%A9s_do_PHP
http://www.php.com.br/view_84?habilitando-o-php-com-suporte-ao-sql-server-no-windows
http://php.net/manual/en/book.sqlsrv.php

Citação:
Verifique a possibilidade de utilizar o mysql, pois creio que seja mais fácil de trabalhar com uma aplicação por ja ser nativo "padrão" da linguagem.

William (devwilliam)
   - 14 jun 2015

Galera eu sei que todos estão tentando ajudar, mas nem sempre existe alternativa para mudar o SGBD, na empresa temos 16 bases de dados com aproximadamente 100 tabelas em cada base, isso fora as procedures e triggers, então ficaria inviável mudar de SGBD.

Citação:
Verifique a possibilidade de utilizar o mysql, pois creio que seja mais fácil de trabalhar com uma aplicação por ja ser nativo "padrão" da linguagem.


Maca, tenho o seguinte código rodando e funcionando perfeitamente:

Minha função no SQL Server, retorna um número inteiro:
#Código

ALTER FUNCTION "dbo"."ContaCaracter" 
(
      @Palavra Varchar(100), @String Varchar(Max)
)
RETURNS int AS
BEGIN
 
      Declare @Count int, @CountTexto int
      Set @CountTexto = 0
      Set @Count = 0
      While @Count <= Len(@String)
      Begin
            Set @CountTexto =
            Case When Substring(@String, @Count, Len(@Palavra)) = @Palavra
                        Then @CountTexto + 1
                        Else @CountTexto
                  End
            Set @Count = @Count + 1
 
      End
      Return @CountTexto
 
END


Chamo essa função usando PDO pode ser com a extensão sqlsrv para Windows ou dblib para Linux as 2 funcionam, os parâmetros estou passando direto mas você pode passar variáveis também:
#Código
$sql = "SELECT dbo.ContaCaracter('dia', 'Bom dia')";
$stm = $pdo->prepare($sql);
$stm->execute();
$retorno = $stm->fetch();

var_dump($retorno);


Já tentei com $pdo->query() mas não deu certo!

Espero que ajude você, qualquer dúvida posta novamente.

Maca
   - 14 jun 2015

William, Wellington, Marcio, obrigado pela ajuda!

Vou estudar tudo isso e qualquer novidade posto aqui.. Abraços

Marcio Araujo
   - 14 jun 2015

Maca, fica tranquilo leia com calma e pode voltar caso necessario.

Maca
   - 15 jun 2015

Prezados bom dia!

William, é exatamente ai onde parei... Vou te explicar brevemente..Esse banco de dados que eu conecto, é o da catraca da empresa, onde os funcionários passam o crachá para refeições, mas este banco por si só, faz conexão com o banco de dados do sistema da indústria, e ai temos duas coisas: os dados dos funcionários por parte da indústria, e todos os registros por parte da catraca... O que interessa a minha aplicação é apenas a conexão a catraca, pois este banco já "conversa" com o da indústria..

Ali em cima, o "$sql = select * from [dbo].[v_relogio_ponto] ('cafe')", é uma função que este banco juntamente ao banco da indústria faz para trazer os registros.. porém dentro do sistema da indústria, temos as variáveis "CAFE_INI", "CAFE_FIM" e etc.. e dentro desse sistema elas estão com valores fixos! (Deixando de ser variável e sendo uma constante). Por exemplo, se você quiser qualquer refeição ai na função, ela só traz registros do mês 4 ao mês 5, e não é isso que eu preciso.. Na minha aplicação, preciso que o que o usuário digitar, o PHP entenda como um valor a ser atribuído para essas variáveis entendeu?

Se o usuário usar os filtros assim, a grosso modo: "Quero todos os funcionários do dia 01/05/15 a 25/05/15 no turno Almoço no modo Sintético", ou "Quero todos os funcionários do dia 05/06/15 a 10/06/15 no turno Café no modo Analítico", quero saber como o PHP vai interpretar isso... A conexão ao banco já ocorre normalmente!!

No seu caso William, você realmente está passando os parâmetros direto.. No meu caso, preciso saber como fazer o $_GET dos filtros conversarem com esses "if's" da função e trazer os dados de acordo.. Pois só "$sql = select * from [dbo].[v_relogio_ponto] ('cafe')" ou 'almoco' / 'janta' etc não adianta, pois fica fixo os registros, ai os meus $_GETs não servem para nada!!

Obs *** Assim como você, não consegui conexão e nem queries utilizando o pdo, apenas com sqlsrv ***

William (devwilliam)
   - 15 jun 2015

Pelo o que entendi, o seu problema na verdade é na função do SQL Server, ela não está preparada para ter essa flexibilidade que você precisa nas datas (pelo menos no trecho que você postou acima), mesmo que você capture os parâmetros.

Vejo 2 situações na sua dúvida:

1 - Sua função (SQL Server) tem que aceitar todos os parâmetros(data_inicial, data_final) que você precisa para processar os dados.

2 - Capturar os valores via PHP e passar para chamada da função no PDO.

#Código

$data_inicial = (isset($_GET['data_inicial'])) ? $_GET['data_inicial'] : '';
$data_final = (isset($_GET['data_final'])) ? $_GET['data_final'] : '';
$tipo = (isset($_GET['tipo'])) ? $_GET['tipo'] : '';


$sql = "SELECT dbo.V_RELOGIO_PONTO('{$tipo}', {$data_inicial}, {$data_tipo})";
$stm = $pdo->prepare($sql);
$stm->execute();
$retorno = $stm->fetch();


Está certa minha análise?

Wellington Pereira
   - 15 jun 2015


Citação:
William, Wellington, Marcio, obrigado pela ajuda!

Vou estudar tudo isso e qualquer novidade posto aqui.. Abraços


Espero ter ajudado

Maca
   - 15 jun 2015

@var = Variável dentro da função SQL
$var = Variável dentro do PHP

Legal William, é nesse rumo que estou indo, isso mesmo, porque se eu coloco SELECT dbo.V_RELOGIO_PONTO where @DATA_INI [ que é a variável dentro da função SQL ] = '$datainicio' já começam aqueles alertas do sqlsrv... Vou testar aqui seu código e qualquer novidade te aviso.. Muito obrigado!

Maca
   - 15 jun 2015

William, como disse estou usando o sqlsrv.. Não consegui fazer os drivers funcionarem para o PDO.. Eu deixei o bloco desse jeito:

#Código

<?php
		// Com o $_GET['totais'] setado, verificamos se o <select> "totais" terá o valor "totalRefeicao".
		// Caso tenha, é exibido na tela informações sobre funcionários e refeições.
		if(@$_GET['totais'] == "totalRefeicao"){
			if(isset($_GET['turnos'])){ // if para verificar se o turno = ligado
				$reg = $_GET['turnos'];
				$dtinicio = $_GET['dtinicio'];
				$dtfim = $_GET['dtfim'];
				$tipo = (isset($_GET['tipo'])) ? $_GET['tipo'] : '';
	
				switch ($reg) {
				case $reg: //se o turno = ligado, faz a consulta no banco para trazer os registros.
				if($_GET['ans'] == "analitico"){ // verifica se o relatorio é do tipo analitico
				
					// bloco de consulta que realiza a paginação em modo analítico
					$sql = "select * from [dbo].[v_relogio_ponto] ('{$tipo}')";
					$res = sqlsrv_query( $conn, $sql );
					
					if( $res === false) {
						die( print_r( sqlsrv_errors(), true) );
					}
					// fim do bloco de consulta para paginação
	
					if($dtinicio == "" && $dtfim == ""){
						echo "<p class='p18' align='center'>Informe as datas para realizar uma consulta analítica.</p>";
					}elseif ($dtinicio > $dtfim) {
						echo "<p class='p18' align='center'>Data final <u>menor</u> que a data de início.</p>";
					}else{ ...	?>


Mas não trouxe nada na tela... o <select> que tem os <options> cafe, almoco, janta e ceia, estão com os values corretos, se eu troco ('{$tipo}') por ('cafe'), ai os registros são exibidos na tela.. Há algum erro neste bloco meu?

**Só para você entender, este isset turnos, é para ver se será filtrado por refeição, ou total do turno, se for refeição cai nesses registros, se for turno, só traz o total de cada turno no período selecionado.. Testei a $tipo dentro do case $reg do switch também, e não trouxe registros..

William (devwilliam)
   - 15 jun 2015

Não tenho como testar essa extensão, mas acho que dá para você tentar com sqlsrv_prepare() e depois sqlsrv_execute() em substituição ao meu código.

Na dúvida dessas funções segue link sqlsrv-prepare e sqlsrv-execute.

Maca
   - 15 jun 2015

Ok William vou testar isso... Obrigado pela ajuda!