103 lines
4.4 KiB
SQL
103 lines
4.4 KiB
SQL
-- SP_Webhook_CaptureEvent — SAP HANA / SQLScript
|
|||
|
|
--
|
||
|
|
-- Equivalente HANA de sp-webhook-capture-event-mssql.sql: toda la lógica
|
||
|
|
-- de captura vive acá, no en el cuerpo de SBO_SP_PostTransactionNotice
|
||
|
|
-- (hook compartido de SAP, ver recreate_sbo_sp_posttransactionnotice_hana.sql).
|
||
|
|
--
|
||
|
|
-- Requiere que la UserTable "@OEVN" ya exista (creada por
|
||
|
|
-- `npm run provision`, ver src/provisioning/).
|
||
|
|
--
|
||
|
|
-- ✅ Verificado contra un HANA real (SAP Business One), instalado y
|
||
|
|
-- funcionando — incluida la sintaxis del EXIT HANDLER y el filtro de eco
|
||
|
|
-- (INSERT...SELECT...WHERE, más abajo): se confirmó que un DELETE vía
|
||
|
|
-- Service Layer sobre una fila de @OEVN ya no genera ningún eco nuevo.
|
||
|
|
-- ⚠️ El filtro por suscripción activa (EXISTS contra @EVC1/@OEVC, más
|
||
|
|
-- abajo) es nuevo y todavía NO se probó contra ese ambiente.
|
||
|
|
--
|
||
|
|
-- U_UserID: no se completa. CURRENT_USER da el usuario de la conexión a
|
||
|
|
-- HANA (una cuenta técnica), no el usuario real de SAP que hizo la
|
||
|
|
-- transacción — confirmado contra este mismo ambiente. Ninguno de los 5
|
||
|
|
-- parámetros que recibe el hook trae ese dato, así que por ahora el campo
|
||
|
|
-- queda sin poblar en las dos variantes (ver también mssql.sql).
|
||
|
|
--
|
||
|
|
-- Name: en una UserTable de SAP, "Name" también debe ser único (no solo
|
||
|
|
-- "Code") — confirmado contra Service Layer real (ODBC -2035 al repetir
|
||
|
|
-- un Name, con Code distinto). Por eso Name usa el mismo UUID que Code:
|
||
|
|
-- cualquier otro valor (como el propio ObjectType) se repite entre
|
||
|
|
-- eventos del mismo tipo y hace fallar el INSERT en el segundo evento
|
||
|
|
-- (en silencio, por el EXIT HANDLER).
|
||
|
|
--
|
||
|
|
-- Eco de nuestras propias escrituras: cualquier POST/PATCH/DELETE que
|
||
|
|
-- hace el dispatcher sobre @OEVC/@EVC1/@OEVN/@EVN1 vía Service Layer
|
||
|
|
-- dispara este mismo hook de nuevo, con un ObjectType especial de SAP
|
||
|
|
-- para "operación genérica sobre una UserTable simple": un código
|
||
|
|
-- negativo + tab + nombre físico de la tabla (confirmado real:
|
||
|
|
-- "-3\t@OEVN" para un DELETE). Si insertáramos esa fila iba a generar
|
||
|
|
-- otro eco al borrarla, indefinidamente — por eso el INSERT usa
|
||
|
|
-- SELECT...FROM DUMMY WHERE en vez de VALUES, para poder filtrar el
|
||
|
|
-- ObjectType sin agregar una rama procedural nueva (ver docs/DISENO.md,
|
||
|
|
-- hallazgo 5).
|
||
|
|
--
|
||
|
|
-- Filtro por suscripción activa: además de lo anterior, solo se inserta
|
||
|
|
-- si existe al menos una fila en @EVC1 (con su @OEVC en State='A') para
|
||
|
|
-- este ObjectType+TransType exacto. No es "lógica de negocio propia" del
|
||
|
|
-- SP — consulta la misma tabla de configuración que ya es la fuente de
|
||
|
|
-- verdad para el dispatcher, no una copia/lista fija a mantener
|
||
|
|
-- sincronizada. Evita ensuciar @OEVN con todo lo que SAP genera y a
|
||
|
|
-- nadie le interesa (en el ambiente de prueba, cientos de eventos por
|
||
|
|
-- minuto sin ninguna suscripción real).
|
||
|
|
|
||
|
|
DROP PROCEDURE "SP_Webhook_CaptureEvent";
|
||
|
|
|
||
|
|
CREATE PROCEDURE "SP_Webhook_CaptureEvent" (
|
||
|
|
IN object_type NVARCHAR(20),
|
||
|
|
IN transaction_type NVARCHAR(1),
|
||
|
|
IN num_of_cols_in_key INTEGER,
|
||
|
|
IN list_of_key_cols_tab_del NVARCHAR(255),
|
||
|
|
IN list_of_cols_val_tab_del NVARCHAR(255),
|
||
|
|
OUT error INTEGER,
|
||
|
|
OUT error_message NVARCHAR(200)
|
||
|
|
)
|
||
|
|
LANGUAGE SQLSCRIPT
|
||
|
|
AS
|
||
|
|
BEGIN
|
||
|
|
DECLARE v_code NVARCHAR(36);
|
||
|
|
|
||
|
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||
|
|
BEGIN
|
||
|
|
error := ::SQL_ERROR_CODE;
|
||
|
|
error_message := SUBSTR(::SQL_ERROR_MESSAGE, 1, 200);
|
||
|
|
END;
|
||
|
|
|
||
|
|
error := 0;
|
||
|
|
error_message := N'Ok';
|
||
|
|
|
||
|
|
-- Sin condiciones de negocio: inserta siempre, salvo que sea un eco
|
||
|
|
-- de una escritura nuestra sobre estas mismas 4 tablas (arriba).
|
||
|
|
SELECT SYSUUID INTO v_code FROM DUMMY;
|
||
|
|
|
||
|
|
INSERT INTO "@OEVN" (
|
||
|
|
"Code", "Name",
|
||
|
|
"U_SourceDB", "U_Status", "U_ObjectType", "U_TransType",
|
||
|
|
"U_FieldsInKe", "U_FieldNames", "U_FieldValue", "U_ReplayStat"
|
||
|
|
)
|
||
|
|
SELECT
|
||
|
|
:v_code, :v_code,
|
||
|
|
CURRENT_SCHEMA, 'N', :object_type, :transaction_type,
|
||
|
|
:num_of_cols_in_key, :list_of_key_cols_tab_del, :list_of_cols_val_tab_del, 'N'
|
||
|
|
FROM DUMMY
|
||
|
|
WHERE NOT (
|
||
|
|
:object_type LIKE '-%' || CHAR(9) || '@OEVC'
|
||
|
|
OR :object_type LIKE '-%' || CHAR(9) || '@EVC1'
|
||
|
|
OR :object_type LIKE '-%' || CHAR(9) || '@OEVN'
|
||
|
|
OR :object_type LIKE '-%' || CHAR(9) || '@EVN1'
|
||
|
|
)
|
||
|
|
AND EXISTS (
|
||
|
|
SELECT 1
|
||
|
|
FROM "@EVC1" f
|
||
|
|
INNER JOIN "@OEVC" s ON s."Code" = f."U_WebhookID"
|
||
|
|
WHERE f."U_ObjectType" = :object_type
|
||
|
|
AND f."U_TransType" = :transaction_type
|
||
|
|
AND s."U_State" = 'A'
|
||
|
|
);
|
||
|
|
END;
|