Files
26ai_mvp_poc/fnc_26ai_query_insights_list.sql
2026-05-08 13:14:56 +00:00

176 lines
9.2 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
create or replace function FNC_26ai_query_INSIGHTS_LIST(p_query_id IN VARCHAR2,
p_comp_id in varchar2,
p_credential in varchar2 default 'OCI_CRED')
return t_26ai_array pipelined parallel_enable
as
l_sql VARCHAR2(4000) ;
l_cursor_id INTEGER;
l_desc_tab dbms_sql.desc_tab;
l_col_cnt INTEGER;
v_labels clob;
v_label_char varchar2(400);
v_label_number varchar2(400);
v_label_date varchar2(400);
v_str_to_llm clob;
v_insigths clob;
v_has number ;
-- funcao pipeline de retorno
v_id number := 0 ;
v_array t_26ai_array := t_26ai_array();
v_ignore_group varchar2(1);
begin
begin
select query_text
into l_sql
from TB_26AI_QUERY_HISTORY
where query_id = p_query_id;
v_has := 1;
exception
when no_data_found then
v_has := 0 ;
dbms_output.put_line(' Registro nao existente para a query ');
end;
if v_has = 1 then
--
-- rotina de identificacao de grupos (data types) baseado nos tipos de dados nas colunas da consulta
--
BEGIN
v_ignore_group := 'N';
l_cursor_id := DBMS_SQL.OPEN_CURSOR;
dbms_sql.parse(l_cursor_id, l_sql, dbms_sql.native);
dbms_sql.describe_columns(l_cursor_id, l_col_cnt, l_desc_tab);
FOR i IN 1..l_col_cnt LOOP
if l_desc_tab(i).col_type not in (2,12) then -- varchar2
v_str_to_llm := v_str_to_llm || 'Column ' || i || ' Data Type VARCHAR2: ' || l_desc_tab(i).col_name || ', ';
v_label_char := v_label_char || l_desc_tab(i).col_name || ', ';
elsif l_desc_tab(i).col_type = 2 then -- number
v_str_to_llm := v_str_to_llm || 'Column ' || i || ' Data Type NUMBER: ' || l_desc_tab(i).col_name || ', ';
v_label_number := v_label_number || l_desc_tab(i).col_name || ', ';
elsif l_desc_tab(i).col_type = 12 then -- date
v_str_to_llm := v_str_to_llm || 'Column ' || i || ' Data Type DATE: ' || l_desc_tab(i).col_name || ', ';
v_label_date := v_label_date || l_desc_tab(i).col_name || ', ';
end if;
END LOOP;
v_labels := 'Colunas: (' || v_label_char || v_label_number || v_label_date || ')';
v_labels := replace(v_labels,', )',')');
EXCEPTION
WHEN OTHERS THEN
v_ignore_group := 'Y';
dbms_output.put_line( sqlerrm );
END;
v_insigths := FNC_26AI_RAG('O SQL executado no Oracle para referência: ' || l_sql || '.' ||
'Colunas e data types: ' || v_str_to_llm || '.' ||
' As colunas são classificadas de 2 tipos:' ||
' Quantificadores: São entidades, fazem a contagem de alguma informação, são as colunas de agru-padores. Ela é a informação para ser analisar.' ||
' O "Geral" será sempre implícito.' ||
' Totalizadores: Fazem a totalização de uma informação, baseada na soma, média, mínimo, máximo, etc.' ||
' O treinamento da IA precisa ser feito para que ela compreenda que colunas de tabelas que:' ||
' As que iniciam com "cd_" e que são PK, são quantificadores/entidades.' ||
' As que iniciam com "dt_" e tem tipo date/datetime/timestamp são informações de uma data, que se pode quebar a informação em dia, mês, ano e dia da semana' ||
' As que iniciam com "qt_" ou possuem "quantidade", "qtde" e são de tipos numéricos (inteiro ou decimais) são informações totalizadoras.' ||
' As que iniciam com "vl" ou possuem "valor" e são de tipos numéricos (inteiro ou decimais) são in-formações totalizadoras.' ||
' Basicamente terá um padrão de nomes. Comentários nas colunas no banco podem ajudar na formatação do resultado do insight, conforme visto mais adiante.' ||
' Os totalizadores compostos são totais extraídos da soma de várias colunas Totalizadoras. Por exemplo, uma consulta que possui as colunas "icms", "ipi", "pis", "cofins" ' ||
' irão possuir os totalizadores conforme vistos antes, com agrupamentos também conforme vistos antes. No entanto, poderá haver também um totalizador composto chamado ' ||
' "Valor dos impostos" que será o resultado da soma desses 4 impostos. Esse totalizador composto é também pode aplicar totalizações pelas colunas Quantificadores ' ||
' (Valor de impostos por geral, Valor de impostos por cd_material, etc).' ||
' Tipos de insights' ||
' Os exemplos anteriores baseiam-se em totalizações por soma, média, mínimo e máximo. Esses exemplos foram simplificados para compreendimento do funcionamento.' ||
' Avançando nesse sentido, para que os insights possam gerar informações de alto nível, outros cálculos de estatística descritiva podem ser adicionados, como média, ' ||
' mediana, moda e desvio padrão, bem como técnicas estatísticas de detecção de anomalias, como granularidades horária, diária, semanais e mensais, além de muitas' ||
' outras utilizadas normalmente em dashboard de BIs.' ||
' Considerando os exemplos que vimos anteriormente, poderão ser gerados insights automáticos para fornecer informações que responderiam as seguintes análises:' ||
' Qual material eu mais movimento?' ||
' Qual dia da semana mais movimento materiais?' ||
' Qual a variação percentual entre o valor mínimo e o máximo do material "X"?' ||
' Qual o maior desvio entre a quantidade do material "Y";' ||
' Qual o maior e menor intervalo de tempo de movimentação de um material?' ||
' Exemplo de insight:' ||
' ID: 1' ||
' Insight: Contagem por cd_material' ||
' Informação: count(*)' ||
' Como: group by cd_material' ||
' Por exemplo: para o Oracle SQL "SELECT CD_MOVIMENTO, DT_MOVIMENTO, CD_MATERIAL, QUANTIDADE, VALOR FROM ESMOVIME" ' ||
' Temos: ' ||
' QUANTIFICADOR: select CD_MOVIMENTO, count(*) FROM ESMOVIME group by CD_MOVIMENTO ' ||
' TOTALIZADOR: select max(QUANTIDADE), min(QUANTIDADE), avg(QUANTIDADE), sum(QUANTIDADE) FROM ESMOVIME ' ||
' Gere insigths deste tipo, incluindo composicao de colunas para que seja possivel gerar maior numero de insigths possivel: ' ||
case
when v_ignore_group = 'N' then
' Composição de colunas VARCHAR2: ' || v_label_char || ' ' ||
' Composição de colunas NUMBER: ' || v_label_number || ' ' ||
' Composição de colunas DATE: ' || v_label_date
end ||
' O resultado deve ser um documento em JSON, com atributos: "tipo" (totalizador ou quantificador), ' ||
' "descricao" (se será uma contagem, soma, média, e sobre qual colunas ou colunas), "insigth", "informacao" ' ||
' (descrição de como realizar o insight), "sql" (comando). ' ||
' Exemplo de JSON e sua estrutura: ' ||
'{ "tipo": "quantificador", ' ||
' "descricao": "Contagem por CD_MOVIMENTO", ' ||
' "insight": "Contagem de movimentos", ' ||
' "informacao": "Count(*)", ' ||
' "sql": "SELECT CD_MOVIMENTO, COUNT(*) FROM ESMOVIME GROUP BY CD_MOVIMENTO" } ' ||
' Certifique-se de que o JSON gerado não contenha comentários, caracteres extras ou ' ||
' qualquer outro elemento que invalide o JSON.', p_credential,p_comp_id);
else -- v_has = 0
dbms_output.put_line(' Insights ja existem para SQL ' || p_query_id );
end if;
dbms_output.put_line(v_insigths);
-- retorno da funcao pipeline
for r1 in ( SELECT jt.tipo, jt.descricao, jt.insight, jt.informacao, jt.sql_query, p_query_id, sysdate
FROM JSON_TABLE(
replace( substr( v_insigths,
instr( v_insigths , '```' ) + 3,
instr( v_insigths , '```',1,2) - instr( v_insigths , '```' ,1,1) - 3
) , 'json', '')
,
'$[*]' COLUMNS (
tipo VARCHAR2(50) PATH '$.tipo',
descricao VARCHAR2(255) PATH '$.descricao',
insight VARCHAR2(255) PATH '$.insight',
informacao VARCHAR2(255) PATH '$.informacao',
sql_query VARCHAR2(1000) PATH '$.sql'
)
) jt ) loop
v_id := v_id + 1;
v_array.extend;
v_array(v_array.last) := t_26ai_insight_record(v_id,
r1.tipo ,
r1.descricao ,
r1.insight ,
r1.informacao ,
r1.sql_query,
p_query_id,
sysdate);
PIPE ROW( v_array(v_id) );
end loop;
end;
/