jheferson-br / tquery
PHP 库用于执行 SQL 文件。仅限 Adianti 项目使用。
README
关于组件
TQuery 类被开发出来,为 Adianti 框架引入了一种不同的查询构建和执行方法。
使用它,可以执行.sql文件,从而将SQL指令与PHP代码分离。
因此,我们可以更好地阅读SQL代码。
安装
由于这是一个composer包,只需使用以下命令:
composer require 'jheferson-br/tquery'
使用示例
为了更好地理解类的工作方式,请看以下简单示例。
假设我们需要在数据库中执行以下指令以清理系统表
TRUNCATE TABLE cliente; TRUNCATE TABLE produto; TRUNCATE TABLE fornecedor;
该文件位于项目根目录的 app/querys/ 文件夹中,名为 LimpaTabelas.sql。
使用TQuery类,代码如下:
TTransaction::open('ERP'); // instanciando o objeto TQuery. $sql = new TQuery("LimpaTabelas.sql"); //Definindo o local onde os arquivos '.sql' serão encontrados. $sql->setBasePathQuerys("app/querys/"); //Definindo um separador de querys para a execução de varios comandos dentro do mesmo arquivo .sql $sql->setMultiQuerySeparator(";"); //Executando as querys. $afected_rows = $sql->execute(); //Imprimindo na tela a quantidade de linhas que sofreram alterações com a execução da query. print_r($afected_rows);
请注意,TQuery类需要在 TTransaction 中打开事务才能执行,这与Adianti框架的标准一致。
此外,所有使用 execute() 方法执行的操作都将记录在Adianti的日志系统中。
TQuery还能够执行查询,如复杂的连接。在框架中,通常建议使用视图,但有时这会变得难以维护。
因此,开发了 load() 方法,该方法可以接收框架自带的 TCriteria 作为参数,从而保持与框架的兼容性。
想象一下需要执行以下复杂的连接
SELECT `mes`.`men_mesano` AS `men_mesano`, `mes`.`men_insc_muni` AS `men_insc_muni`, `mes`.`men_conta` AS `men_conta`, `pla`.`pla_bacen`, `mes`.`cod_trib_desif` AS `cod_trib_desif`, SUM(if(COALESCE(`mes`.`men_mes_santer`,0) < 0, 0, COALESCE(`mes`.`men_mes_santer`,0))) AS `sald_inic`, SUM(COALESCE(`mes`.`men_cred_mes`,0)) AS `men_cred_mes`, SUM(COALESCE(`mes`.`men_deb_mes`,0)) AS `men_deb_mes`, SUM(COALESCE(`mes`.`men_tributavel`,0)) AS `men_tributavel`, SUM(COALESCE(`mes`.`men_deducao`,0)) AS `men_deducao`, SUM(COALESCE(`mes`.`men_tributavel`,0)) - SUM(`mes`.`men_deducao`) AS `base_calc`, ( SUM(COALESCE(`mes`.`men_tributavel`,0)) - SUM(COALESCE(`mes`.`men_deducao`,0)) ) * COALESCE(`mes`.`men_aliquota`,0) / 100 AS `valr_issqn_retd`, `mes`.`men_desc_dedu` AS `men_desc_dedu`, `mes`.`men_aliquota` AS `men_aliquota`, `mes`.`men_incentivo` AS `men_incentivo`, `mes`.`men_desc_incen` AS `men_desc_incen`, `mes`.`men_motivo_nao_exig` AS `men_motivo_nao_exig`, `mes`.`men_processo_nao_exig` AS `men_processo_nao_exig`, `mes`.`men_mes_compensacao` AS `men_mes_compensacao`, `mes`.`men_vlr_compensacao` AS `men_vlr_compensacao`, `pac`.`cnpj` AS `cnpj` FROM ( des_plano AS pla LEFT JOIN `des_mensal` AS `mes` ON (pla.pla_conta = mes.men_conta) LEFT JOIN `des_pacs` AS `pac` ON ( `mes`.`men_insc_muni` = `pac`.`insc_muni` ) ) {{WHERE}} GROUP BY `mes`.`men_mesano`, `pac`.`insc_muni`, `mes`.`men_conta`, `mes`.`men_aliquota`
请注意,查询条件中存在一个名为 {{WHERE}} 的占位符。这个占位符是TQuery的标准占位符,其目的是定义WHERE条件的插入位置。
以下是PHP代码示例
TTransaction::open('ERP'); //Definindo os critérios de busca $criteria = new TCriteria(); $criteria->add(new TFilter('men_mesano', 'LIKE', "%" . date('Y'))); // instanciando o objeto TQuery. $sql = new TQuery("QryRelatorio.sql"); //Definindo o local onde os arquivos '.sql' serão encontrados. $sql->setBasePathQuerys("app/querys/"); //Executando a query e carregando os objetos $rows = $sql->load($criteria); //Imprimindo na tela os resultados da consulta. print_r($rows);
请注意,TQuery的行为与TRepository相似
还可以通过自定义占位符传递查询参数。这在我们需要向TQuery发送SQL代码片段时非常有用。
请看以下示例
SELECT '12/{{mes_ano}}' AS men_mesano, '{{men_insc_muni}}' AS men_insc_muni, pla_conta AS men_conta, pla.pla_bacen AS pla_bacen, pla.cod_trib_desif AS cod_trib_desif, 0 AS sald_inic, 0 AS men_cred_mes, 0 AS men_deb_mes, 0 AS men_tributavel, 0 AS men_deducao, 0 AS base_calc, 0 AS valr_issqn_retd, 0 AS men_desc_dedu, aliq.`alq_taxa` AS men_aliquota, 0 AS men_incentivo, 0 AS men_desc_incen, 0 AS men_motivo_nao_exig, 0 AS men_processo_nao_exig, 0 AS men_mes_compensacao, 0 AS men_vlr_compensacao, '{{cnpj}}' AS cnpj FROM des_plano AS pla LEFT JOIN des_aliquota AS aliq ON aliq.`cid_cod` = (SELECT cid_cod FROM des_coop WHERE coo_cnpj = '{{cnpj}}') AND aliq.`cod_desif` = pla.`cod_trib_desif` WHERE pla_conta IN (SELECT men_conta FROM des_mensal as mct WHERE ( CAST(CONCAT(SUBSTR(mct.men_mesano, 4,4),SUBSTR(mct.men_mesano, 1,2))AS UNSIGNED INTEGER) between CAST(CONCAT(SUBSTR('01/{{mes_ano}}', 4,4),SUBSTR('01/{{mes_ano}}', 1,2))AS UNSIGNED INTEGER) and CAST(CONCAT(SUBSTR('12/{{mes_ano}}', 4,4),SUBSTR('12/{{mes_ano}}', 1,2))AS UNSIGNED INTEGER) ) and mct.poa_cod = '{{poa_cod}}') AND pla_conta LIKE '7%' and pla.pla_grau = 6 and pla.pla_arquivo = 1 GROUP BY `men_mesano`, men_insc_muni, `men_conta`, `men_aliquota`
请注意,此查询包含多个自定义占位符,如 {{poa_cod}} 和 {{cnpj}}。要向TQuery发送数据,以便将其用于自定义占位符,只需在对象构造函数的第二个参数中发送一个关联数组,其中键名与占位符名称相同。
以下是对先前查询的执行示例
TTransaction::open('ERP'); //Definindo os critérios de busca $criteria = new TCriteria(); $criteria->add(new TFilter('men_mesano', 'LIKE', "%" . date('Y'))); //Defininto vetor com mnemônicos customizados $params = [ "mes_ano"=> $mes_ano, "cnpj"=> $PA->cnpj, "poa_cod"=> $PA->poa_cod, "men_insc_muni"=> $PA->insc_muni, ]; // instanciando o objeto TQuery informando os parâmtros q serão utilizados. $sql = new TQuery("QryRelatorio.sql", $params); //Definindo o local onde os arquivos '.sql' serão encontrados. $sql->setBasePathQuerys("app/querys/"); //Executando a query e carregando os objetos $rows = $sql->load($criteria); //Imprimindo na tela os resultados da consulta. print_r($rows);
还可以通过 setParams 方法设置占位符的值,该方法接收一个包含值的数组作为参数。以下是代码示例
$sql->setParams($params);