AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / 问题

All perguntas(dba)

Martin Hope
RonJohn
Asked: 2025-04-18 01:31:41 +0800 CST

DB2 LUW - O diretório db2/V11.5 é necessário para o V11.5.7.0?

  • 5

De acordo com db2level, atualmente estamos executando o DB2 v11.5.7.0 (no RHEL 7.9). Ele foi atualizado da versão 11.5 antes da minha chegada.

Isso pode parecer uma pergunta estúpida, mas os arquivos V11.5 são necessários para o V11.5.7.0 ou o V11.5.7.0 é totalmente autônomo, então posso removê-lo /opt/ibm/db2/V11.5?

(Acho que a resposta é "sim", mas não há nenhum sistema de teste para eu experimentar e não quero interromper a produção.)

Ambos V11.5/e V11.5.7.0veja se são instalações completas:

$ du -cm -d1 /opt/ibm/db2
du: cannot read directory ‘/opt/ibm/db2/V11.5/.licbkup’: Permission denied
2270    /opt/ibm/db2/V11.5
du: cannot read directory ‘/opt/ibm/db2/V11.5.7.0/.licbkup’: Permission denied
2150    /opt/ibm/db2/V11.5.7.0
4420    /opt/ibm/db2
4420    total

Mais detalhes:

$ /sbin/lsof -u db2dlp01 | grep V11.5/
$ echo $?
1

$ /sbin/lsof -u db2dlp01 | grep -q V11.5.7.0
$ echo $?
0

$ /opt/ibm/db2/V11.5/bin/db2greg -dump
S,DB2,11.5.0.0,/opt/ibm/db2/V11.5,,,0,0,,1610467335,0
V,DB2GPRF,DB2SYSTEM,ewr0vlpudb01dol,/opt/ibm/db2/V11.5,
S,TSA,4.1.0.7,/opt/IBM/tsamp,DG_NOT_ALLOWED,DB2_INSTALLED,0,0,-,1651371491,0
S,RSCT,3.2.6.2,/usr/sbin/rsct,DG_NOT_ALLOWED,DB2_INSTALLED,0,0,-,1651371491,0
S,DB2,11.5.7.0,/opt/ibm/db2/V11.5.7.0,,,0,0,,1651371660,0
V,DB2GPRF,DB2SYSTEM,ewr0vlpudb01dol,/opt/ibm/db2/V11.5.7.0,
I,DB2,11.5.7.0,db2dlp01,/home/db2dlp01/sqllib,,1,0,/opt/ibm/db2/V11.5.7.0,,

$ /opt/ibm/db2/V11.5.7.0/bin/db2greg -dump
S,DB2,11.5.0.0,/opt/ibm/db2/V11.5,,,0,0,,1610467335,0
V,DB2GPRF,DB2SYSTEM,ewr0vlpudb01dol,/opt/ibm/db2/V11.5,
S,TSA,4.1.0.7,/opt/IBM/tsamp,DG_NOT_ALLOWED,DB2_INSTALLED,0,0,-,1651371491,0
S,RSCT,3.2.6.2,/usr/sbin/rsct,DG_NOT_ALLOWED,DB2_INSTALLED,0,0,-,1651371491,0
S,DB2,11.5.7.0,/opt/ibm/db2/V11.5.7.0,,,0,0,,1651371660,0
V,DB2GPRF,DB2SYSTEM,ewr0vlpudb01dol,/opt/ibm/db2/V11.5.7.0,
I,DB2,11.5.7.0,db2dlp01,/home/db2dlp01/sqllib,,1,0,/opt/ibm/db2/V11.5.7.0,,

Mais informações:

$ /usr/local/bin/db2ls
Install Path                       Level   Fix Pack   Special Install Number   Install Date                  Installer UID 
---------------------------------------------------------------------------------------------------------------------
/opt/ibm/db2/V11.5               11.5.0.0        0                            Tue Jan 12 11:02:15 2021 EST             0 
/opt/ibm/db2/V11.5.7.0           11.5.7.0        0                            Sat Apr 30 22:21:00 2022 EDT             0 
db2
  • 2 respostas
  • 50 Views
Martin Hope
Manuel Jordan
Asked: 2025-04-18 01:24:26 +0800 CST

Quando usar o comando SHOW PROCESSLIST vs SELECT * FROM information_schema.PROCESSLIST?

  • 8

Na comunidade do servidor MySQL 8, os dois comandos a seguir mostram a mesma estrutura:

SHOW PROCESSLIST;
SELECT * FROM information_schema.PROCESSLIST;

Pergunta

  • Quando usar o comando SHOW PROCESSLISTvs SELECT * FROM information_schema.PROCESSLIST?

Cada comando existe por um motivo específico, certo?

Sobre suas saídas, encontrei apenas duas diferenças para as colunas Statee Infopara cada comando, respectivamente:

State     | Info
----------------------------
init      | SHOW PROCESSLIST
executing | SELECT * FROM information_schema.PROCESSLIST

A diferença da Infocoluna é clara porque ela representa o próprio comando que foi executado , mas :

  • StatePor que a coluna é diferente ?

Está claro o executingvalor, mas:

  • O que significa o initvalor?
mysql
  • 1 respostas
  • 100 Views
Martin Hope
KooMaraLaHam
Asked: 2025-04-17 11:19:17 +0800 CST

Como carregar rapidamente uma grande quantidade de dados de um arquivo CSV e gravá-los em um banco de dados?

  • 4
Esta pergunta foi migrada do Stack Overflow porque pode ser respondida no Database Administrators Stack Exchange. Migrada há 6 dias .

Nome do produto

OceanBase V4.2.5 - Versão da comunidade

Descrição do problema

cluster de implantação obd:
três máquinas 1-1-1, 16c64G, limite de memória=32G

Importar arquivo csv, 100 milhões de dados, 100 partições por campo de tempo, nenhuma chave primária definida

Eu uso este método para importar dados:
load data/ + parallel(9) load_batch_size(18) /

O resultado é muito demorado

Como lidar com isso para importar rapidamente 100 milhões de dados?


Configurações de locatário integradas ao sistema:

alter system set system_memory=‘15g’; 
alter resource unit sys_unit_config max_memory=‘15g’,min_memory=‘15g’; 
#Tuning Parameters 
alter system set enable_merge_by_turn= False; 
alter system set trace_log_slow_query_watermark=‘100s’; 
alter system set max_kept_major_version_number=1; 
alter system set enable_sql_operator_dump=True; 
alter system set _hash_area_size=‘3g’; 
alter system set memstore_limit_percentage=50; 
alter system set enable_rebalance=False; 
alter system set memory_chunk_cache_size=‘1g’; 
alter system set minor_freeze_times=5; 
alter system set merge_thread_count=20; 
alter system set cache_wash_threshold=‘30g’; 
alter system set _ob_enable_prepared_statement=true; 
##Adjust the log level and number of saved logs 
alter system set syslog_level=‘PERF’; 
alter system set max_syslog_file_count=100; 
alter system set enable_syslog_recycle=‘True’; 

Personalize as configurações do locatário:

CREATE RESOURCE UNIT unit1 max_cpu = 9,max_memory = 3006477108,min_memory = 3006477108, max_iops = 10000,min_iops = 1280,max_session_num = 3000,max_disk_size = 214748364800 – 200 GB; 
set global NLS_DATE_FORMAT=‘YYYY-MM-DD HH24:MI:SS’; 
set global NLS_TIMESTAMP_FORMAT=‘YYYY-MM-DD HH24:MI:SS.FF’; 
set global NLS_TIMESTAMP_TZ_FORMAT=‘YYYY-MM-DD HH24:MI:SS.FF TZR TZD’; 
set global ob_sql_work_area_percentage=80; 
set global optimizer_use_sql_plan_baselines = true; 
set global optimizer_capture_sql_plan_baselines = true; 
alter system set ob_enable_batched_multi_statement=‘true’; 
##Set under the tenant to prevent transaction timeout
show variables like ‘%timeout%’; 
set global ob_query_timeout=72000000000; 
set global ob_trx_timeout=72000000000; 
set global max_allowed_packet=67108864; 
#Execute load data permission
set global secure_file_priv=’’; 
grant file on *.* to sqluser01;
csv
  • 1 respostas
  • 74 Views
Martin Hope
cccllll
Asked: 2025-04-15 02:44:49 +0800 CST

bloqueio de linha mysql/postgresql em cenários de alta simultaneidade

  • 5

eu tenho uma transação simples com nível de isolamento READ COMMITTED A configuração da tabela é simples

create table example.parent_tbl(
id int auto_increment primary key
);

create table example.child_tbl(
id int auto_increment primary key,
parent_id int not null,
update_dt timestamp default current_timestamp ON UPDATE current_timestamp,

foreign key (parent_id) references parent_tbl(id),
unique (parent_id)
);
select 
p.*
from example.parent_tbl p
where p.id not in (select parent_id from example.child_tbl)
limit 1
for update
skip locked; 

depois disso, inserirei um novo registro com parent_tbl.idinto child_tbl.

A coluna ID child_tblé única. Tenho vários processos em execução em paralelo e, ocasionalmente, um deles gera uma exceção de integridade, pois o mesmo ID child_tbljá existe.

PERGUNTA

por que uma transação pode selecionar um ID que aparece em child_tbl?

A lógica parece trivial.

Ou a transação A mantém o bloqueio de linha parent_tblantes da confirmação, então a transação B irá ignorá-lo.

OU

A transação A foi confirmada e a cláusula where da transação B filtrará a linha e a ignorará.

Mas a verdade é que não é bem assim!!!


O log de consulta geral mostra o comportamento contraintuitivo deste mecanismo de bloqueio

log do lado do servidor

Há dois processos em execução em paralelo, fazendo a mesma coisa. Neste caso, eles são os threads 60 e 61, respectivamente.

Dois resultados são observados.

  1. A thread 61 inseriu o ID 113 na tabela filha e liberou o bloqueio de linha. A thread 60 executa a consulta, mas não consegue detectar a linha com o ID 113 recém-inserida pela thread 61.

  2. o thread 61 inseriu o id 113 na child_tbl e logo antes de confirmar e liberar o bloqueio de linha, outro thread 60 executa a consulta e adquire o mesmo bloqueio de linha da parent_tbl .


Adicional

Fiz os mesmos testes com o PostgreSQL e também encontrei uma exceção.

mysql
  • 1 respostas
  • 59 Views
Martin Hope
Sig
Asked: 2025-04-14 17:41:11 +0800 CST

Usando variáveis ​​na cláusula where

  • 7

Tenho o que considero ser um problema relativamente simples, mas depois de meia hora ainda não tenho ideia de como resolvê-lo.

Em uma WHEREcláusula de consulta do PostgreSQL, preciso me referir a um valor em vez de usá-lo diretamente. A consulta será executada dentro de um script Ruby, e não posso interpolar diretamente o valor que preciso obter do meu ambiente.

Minha pergunta é

CREATE MATERIALIZED VIEW my_mat_view AS
SELECT  ...
...
WHERE occurred_at BETWEEN NOW() - INTERVAL '?? HOURS' AND NOW()

E o número de horas usado para calcular o intervalo é definido na INTERVAL_HOURSvariável de ambiente. Como mencionado, posso substituir ??pela interpolação porque está entre aspas simples.

Minha ideia é usar uma variável (ou algo que produza o mesmo resultado) para mover a interpolação para fora das aspas simples.

A opção mais próxima da solução que encontro é

DO $$
DECLARE myVar INT;
BEGIN
myVar := #{ENV['INTERVAL_HOURS'};
CREATE MATERIALIZED VIEW my_mat_view AS
SELECT  ...
...
WHERE occurred_at BETWEEN NOW() - INTERVAL 'myVar HOURS' AND NOW()
END $$;

Que deve interpolar corretamente, mas produz

Query 1 ERROR at Line 1: : ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function inline_code_block line 5 at SQL statement

Tentei substituir SELECTpor PERFORM, mas a visualização não foi criada (e nenhum erro foi retornado).

O que estou esquecendo aqui? Posso seguir um caminho diferente (por exemplo, WITHuma cláusula)?

postgresql
  • 1 respostas
  • 196 Views
Martin Hope
Suleyman Essa
Asked: 2025-04-13 20:55:46 +0800 CST

Por que obtenho um spool de índice em um heap em uma subconsulta escalar?

  • 5

Eu estava lendo isso e fiz o seguinte:

go
create table fiirst (
col1 int,
col2 int
);
create table seecond(
col1 int,
col2 int
);
with
n1(c) as (select 0 union all select 0 ),
n2(c) as ( select 0 from n1 as t1 cross join n1 as t2),
n3(c) as ( select 0 from n2 as t1 cross join n2 as t2),
n4(c) as (select 0 from n3 as t1 cross join n3 as t2),
ids(id) as (select ROW_NUMBER() over (order by (select null)) from n4)
insert into fiirst(col1,col2)
select id,id 
from ids;
with
n1(c) as (select 0 union all select 0 ),
n2(c) as ( select 0 from n1 as t1 cross join n1 as t2),
n3(c) as ( select 0 from n2 as t1 cross join n2 as t2),
n4(c) as (select 0 from n3 as t1 cross join n3 as t2),
ids(id) as (select ROW_NUMBER() over (order by (select null)) from n4)
insert into seecond(col1,col2)
select id,id
from ids;
----Craig Freedman's query

select *
from fiirst
where fiirst.col1 > (
    select min(seecond.col1)
    from seecond
    where seecond.col2 < fiirst.col2
);

E eu obtive um spool de índice , mesmo a tabela sendo um heap. A questão é: como isso aconteceu? Por que eu obtenho um spool de índice em um heap? No exemplo mencionado no link acima, não havia linhas, então não havia spools, mas aqui eu os vejo?

sql-server
  • 1 respostas
  • 139 Views
Martin Hope
ConanTheGerbil
Asked: 2025-04-12 17:12:40 +0800 CST

Atualizando uma visão materializada do PostgreSQL e retornando a contagem de linhas

  • 6

Imediatamente após atualizar uma visualização materializada no Postgres, gostaria de saber quantas linhas há nela.

Atualmente faço isso executando um segundo comando SQL ( SELECT count(*) FROM...)

Existe uma maneira mais eficiente de fazer isso? É possível persuadir o comando REFRESH a retornar a contagem de linhas?

postgresql
  • 1 respostas
  • 24 Views
Martin Hope
Ken Ingram
Asked: 2025-04-12 15:09:57 +0800 CST

Existe um método básico para depurar problemas de conexão do cliente MySQL quando o servidor está bom?

  • 5

A máquina que serve o MySQL está funcionando bem. Duas outras máquinas se conectam usando o cliente MySQL sem problemas. Uma máquina na rede parou de se conectar espontaneamente.

Eu tentei strace mysql -h servere a tentativa foi rejeitada imediatamente

Não sei como solucionar o que está causando a falha repentina.

EDIT: Desculpe. Esqueci de incluir o erro:

ERROR 2003 (HY000): Can't connect to MySQL server on 'server1:3308' (111)

Isso é interessante. O outro servidor que acessa o banco de dados não tem problemas:

mysql -h server2 -P3308 -u root -p

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 16591
Server version: 5.5.62 MySQL Community Server (GPL)

Copyright (c) 2000, 2025, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Então, o servidor onde o banco de dados está rodando está funcionando corretamente. Por algum motivo, server1a conexão foi recusada.

A autenticação permite conexões remotas de dentro da intranet.

Qualquer pesquisa no Google assume que o problema está no servidor e não no cliente, então não encontrei nada relevante sobre falha de conexão do cliente ser um problema do cliente.

Alguém que está lendo isso teve esse problema e o resolveu?

mysql
  • 1 respostas
  • 25 Views
Martin Hope
DevQt
Asked: 2025-04-12 10:31:30 +0800 CST

Agrupando e organizando dados usando FOR JSON PATH e INCLUDE_NULL_VALUES

  • 5

Estou com um problema com meu script T-SQL. Estou pensando e trabalhando em como produzir a saída esperada dele.

Aqui está meu script T-SQL:

DECLARE @user_id VARCHAR(50) = 'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL'; -- FOR TESTING PURPOSES ONLY
DECLARE @status_t TABLE (status VARCHAR(50));
INSERT INTO @status_t VALUES ('PENDING'),('APPROVED'),('PROCESSING')

SELECT
    orders.batch_code, -- FOR DEMONSTRATION PURPOSES ONLY
    oa_prod.nested_data AS nested_prod,
    cnb.amount_to_pay
FROM
    [testDB].[dbo].[Orders] AS orders
RIGHT OUTER JOIN
    [testDB].[dbo].[Payment] AS cnb
ON
    orders.order_id = cnb.order_id
LEFT OUTER JOIN
    [testDB].[dbo].[StatusRef] AS stat_ref
ON
    orders.stat_ref_id = stat_ref.stat_ref_id
CROSS APPLY( -- OR OUTER APPLY
    SELECT
        orders.batch_code,
        orders.order_id,
        prod.prod_name,
        pv_kn.key_name,
        pv_kv.value,
        CASE WHEN
            orders.prod_id IS NOT NULL
        THEN
            prod.disc_price
        WHEN
            orders.prod_var_id IS NOT NULL
        THEN
            prod_var.disc_price
        END AS disc_price,
        orders.quantity
    FROM
        [testDB].[dbo].[Product] AS prod
    RIGHT OUTER JOIN
        [testDB].[dbo].[SubProduct] AS prod_var
    ON
        prod.prod_id = prod_var.prod_id
    LEFT OUTER JOIN
        [testDB].[dbo].[SubProductVarKeyValue] AS pv_kv
    ON
        prod_var.prod_var_id = pv_kv.prod_var_id
    LEFT OUTER JOIN
        [testDB].[dbo].[SubProductVarKeyNames] AS pv_kn
    ON
        pv_kv.pv_key_name_id = pv_kn.pv_key_name_id
    WHERE       
        prod.prod_id = orders.prod_id
        OR prod_var.prod_var_id = orders.prod_var_id
    FOR JSON PATH,
    INCLUDE_NULL_VALUES
) AS oa_prod(nested_data) -- it's a syntax analyzer lint conflict ONLY
WHERE
    orders.disable = 0
    AND cnb.disable = 0
    AND orders.user_id = @user_id
    AND stat_ref.com_usd_wrds IN (SELECT status FROM @status_t)
ORDER BY
    orders.dt_stamp DESC,
    orders.batch_code ASC -- To prevent batch_code from being separated
FOR JSON PATH,
INCLUDE_NULL_VALUES

Aqui está meu exemplo mínimo e reproduzível usando variáveis ​​de tabela:

DECLARE @StatusRef TABLE(
    stat_ref_id VARCHAR(50) PRIMARY KEY NOT NULL,
    com_usd_wrds NVARCHAR(100) NOT NULL
);

DECLARE @Product TABLE(
    prod_id VARCHAR(50) PRIMARY KEY NOT NULL,
    prod_name VARCHAR(200) NOT NULL,
    stock INT NOT NULL,
    disc_price DECIMAL(12, 2) NOT NULL
);

DECLARE @SubProduct TABLE(
    prod_var_id VARCHAR(50) PRIMARY KEY NOT NULL,
    stock INT NOT NULL,
    disc_price DECIMAL(12, 2) NOT NULL,
    prod_id VARCHAR(50) NOT NULL
);

DECLARE @Orders TABLE(
    order_id VARCHAR(50) PRIMARY KEY NOT NULL,
    batch_code VARCHAR(50) NULL,
    quantity INT NOT NULL,
    stat_ref_id VARCHAR(50) NOT NULL,
    disable BIT DEFAULT (0) NOT NULL,
    dt_stamp DATETIME NOT NULL,
    prod_id VARCHAR(50) NULL,
    prod_var_id VARCHAR(50) NULL,
    user_id VARCHAR(50) NOT NULL
);

DECLARE @Payment TABLE(
    amount_to_pay DECIMAL(14, 2) NOT NULL,
    order_id VARCHAR(50) NOT NULL,
    disable BIT DEFAULT (0) NOT NULL
);

DECLARE @SubProductVarKeyValue TABLE(
    value VARCHAR(100) NOT NULL,
    prod_var_id VARCHAR(50) NOT NULL,
    pv_key_name_id VARCHAR(50) NOT NULL
);

DECLARE @SubProductVarKeyNames TABLE(
    pv_key_name_id VARCHAR(50) PRIMARY KEY NOT NULL,
    key_name VARCHAR(100) NOT NULL
);

INSERT INTO @StatusRef
VALUES
(
    'STAT-REF-1001', -- stat_ref_id
    'PENDING' -- com_usd_wrds
),
(
    'STAT-REF-1002', -- stat_ref_id
    'APPROVED' -- com_usd_wrds
),
(
    'STAT-REF-1003', -- stat_ref_id
    'PROCESSING' -- com_usd_wrds
);

INSERT INTO @Product
VALUES
(
    'PROD-ID-1001', -- prod_id
    'iPhone', -- prod_name
    0, -- stock | dependent to @SubProduct
    0.00 -- disc_price | dependent to @SubProduct
),
(
    'PROD-ID-1002', -- prod_id
    'Samsung', -- prod_name
    0, -- stock | dependent to @SubProduct
    0.00 -- disc_price | dependent to @SubProduct
),
(
    'PROD-ID-1003', -- prod_id
    'Nokia', -- prod_name
    75, -- stock
    33150.00 -- disc_price
),
(
    'PROD-ID-1004', -- prod_id
    'Google', -- prod_name
    100, -- stock
    53509.00 -- disc_price
),
(
    'PROD-ID-1005', -- prod_id
    'Sony', -- prod_name
    0, -- stock | dependent to @SubProduct
    0.00 -- disc_price | dependent to @SubProduct
),
(
    'PROD-ID-1006', -- prod_id
    'Lenovo', -- prod_name
    0, -- stock | dependent to @SubProduct
    0.00 -- disc_price | dependent to @SubProduct
);

INSERT INTO @SubProduct
VALUES
(
    'PROD-VAR-ID-1', -- prod_var_id
    25, -- stock
    45809.00, -- disc_price
    'PROD-ID-1001' -- prod_id
),
(
    'PROD-VAR-ID-2', -- prod_var_id
    50, -- stock
    40209.00, -- disc_price
    'PROD-ID-1002' -- prod_id
),
(
    'PROD-VAR-ID-3', -- prod_var_id
    0, -- stock | dependent to @Product
    0.00, -- disc_price | dependent to @Product
    'PROD-ID-1003' -- prod_id
),
(
    'PROD-VAR-ID-4', -- prod_var_id
    0, -- stock | dependent to @Product
    0.00, -- disc_price | dependent to @Product
    'PROD-ID-1004' -- prod_id
),
(
    'PROD-VAR-ID-5', -- prod_var_id
    125, -- stock
    25809.00, -- disc_price
    'PROD-ID-1005' -- prod_id
),
(
    'PROD-VAR-ID-6', -- prod_var_id
    150, -- stock
    49100.00, -- disc_price
    'PROD-ID-1006' -- prod_id
);

INSERT INTO @SubProductVarKeyValue
VALUES
(
    'new', -- value
    'PROD-VAR-ID-1', -- prod_var_id
    'PVKN-ID-1' -- pv_key_name_id
),
(
    'new', -- value
    'PROD-VAR-ID-2', -- prod_var_id
    'PVKN-ID-1' -- pv_key_name_id
),
(
    'new', -- value
    'PROD-VAR-ID-5', -- prod_var_id
    'PVKN-ID-1' -- pv_key_name_id
),
(
    'new', -- value
    'PROD-VAR-ID-6', -- prod_var_id
    'PVKN-ID-1' -- pv_key_name_id
)

INSERT INTO @SubProductVarKeyNames
VALUES
(
    'PVKN-ID-1', -- pv_key_name_id
    'Condition' -- key_name
)

INSERT INTO @Orders
(
    order_id,
    batch_code,
    quantity,
    stat_ref_id,
    dt_stamp,
    prod_id,
    prod_var_id,
    user_id
)
VALUES
(
    'ORDER-2025-04-11-B71D0E2F5D8C', -- order_id
    NULL, -- batch_code
    1, -- quantity
    'STAT-REF-1003', -- stat_ref_id
    '2025-04-14 10:17:20.963', -- dt_stamp
    NULL, -- prod_id
    'PROD-VAR-ID-1', -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-11-D95EB033CA40', -- order_id
    'BGUID-2025-04-11-6D81B58FAE94', -- batch_code
    2, -- quantity
    'STAT-REF-1001', -- stat_ref_id
    '2025-04-13 09:17:20.963', -- dt_stamp
    NULL, -- prod_id
    'PROD-VAR-ID-2', -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-11-7F04EFA2BB60', -- order_id
    'BGUID-2025-04-11-6D81B58FAE94', -- batch_code
    2, -- quantity
    'STAT-REF-1001', -- stat_ref_id
    '2025-04-13 09:17:20.963', -- dt_stamp
    'PROD-ID-1003', -- prod_id
    NULL, -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-10-3F03EAA47686', -- order_id
    'BGUID-2025-04-10-20239FD2059F', -- batch_code
    1, -- quantity
    'STAT-REF-1002', -- stat_ref_id
    '2025-04-12 08:17:20.963', -- dt_stamp
    'PROD-ID-1004', -- prod_id
    NULL, -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-10-F4A89E2C4A30', -- order_id
    'BGUID-2025-04-10-20239FD2059F', -- batch_code
    1, -- quantity
    'STAT-REF-1002', -- stat_ref_id
    '2025-04-12 08:17:20.963', -- dt_stamp
    NULL, -- prod_id
    'PROD-VAR-ID-5', -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-08-31BD887341FA', -- order_id
    NULL, -- batch_code
    1, -- quantity
    'STAT-REF-1001', -- stat_ref_id
    '2025-04-11 07:17:20.963', -- dt_stamp
    NULL, -- prod_id
    'PROD-VAR-ID-6', -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
);

INSERT INTO @Payment
(
    amount_to_pay,
    order_id
)
VALUES
(
    45809.00, -- amount_to_pay
    'ORDER-2025-04-11-B71D0E2F5D8C' -- order_id
),
(
    146718.00, -- amount_to_pay
    'ORDER-2025-04-11-D95EB033CA40' -- order_id
),
(
    146718.00, -- amount_to_pay
    'ORDER-2025-04-11-7F04EFA2BB60' -- order_id
),
(
    79318.00, -- amount_to_pay
    'ORDER-2025-04-10-3F03EAA47686' -- order_id
),
(
    79318.00, -- amount_to_pay
    'ORDER-2025-04-10-F4A89E2C4A30' -- order_id
),
(
    49100.00, -- amount_to_pay
    'ORDER-2025-04-08-31BD887341FA' -- order_id
);
SELECT * FROM @StatusRef

SAÍDA:

stat_ref_id com_usd_wrds
STAT-REF-1001 PENDENTE
STAT-REF-1002 APROVADO
STAT-REF-1003 PROCESSAMENTO
SELECT * FROM @Product

SAÍDA:

id_do_produto nome_do_produto estoque preço_disc
PROD-ID-1001 iPhone 0 0,00
PROD-ID-1002 Samsung 0 0,00
PROD-ID-1003 Nokia 75 33150,00
PROD-ID-1004 Google 100 53509,00
PROD-ID-1005 Sony 0 0,00
PROD-ID-1006 Lenovo 0 0,00
SELECT * FROM @SubProduct

SAÍDA:

id_var_do_produto estoque preço_disc id_do_produto
PROD-VAR-ID-1 25 45809,00 PROD-ID-1001
PROD-VAR-ID-2 50 40209,00 PROD-ID-1002
PROD-VAR-ID-3 0 0,00 PROD-ID-1003
PROD-VAR-ID-4 0 0,00 PROD-ID-1004
PROD-VAR-ID-5 125 25809,00 PROD-ID-1005
PROD-VAR-ID-6 150 49100,00 PROD-ID-1006
SELECT * FROM @Orders ORDER BY dt_stamp

SAÍDA:

id_do_pedido código_de_lote quantidade stat_ref_id desabilitar dt_stamp id_do_produto id_var_do_produto ID do usuário
ORDEM-2025-04-08-31BD887341FA NULO 1 STAT-REF-1001 0 2025-04-11 07:17:20.963 NULO PROD-VAR-ID-6 UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
ORDEM-2025-04-10-3F03EAA47686 BGUID-2025-04-10-20239FD2059F 1 STAT-REF-1002 0 2025-04-12 08:17:20.963 PROD-ID-1004 NULO UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
ORDEM-2025-04-10-F4A89E2C4A30 BGUID-2025-04-10-20239FD2059F 1 STAT-REF-1002 0 2025-04-12 08:17:20.963 NULO PROD-VAR-ID-5 UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
PEDIDO-2025-04-11-7F04EFA2BB60 BGUID-2025-04-11-6D81B58FAE94 2 STAT-REF-1001 0 2025-04-13 09:17:20.963 PROD-ID-1003 NULO UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
ORDEM-2025-04-11-D95EB033CA40 BGUID-2025-04-11-6D81B58FAE94 2 STAT-REF-1001 0 2025-04-13 09:17:20.963 NULO PROD-VAR-ID-2 UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
ORDEM-2025-04-11-B71D0E2F5D8C NULO 1 STAT-REF-1003 0 2025-04-14 10:17:20.963 NULO PROD-VAR-ID-1 UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
SELECT * FROM @Payment

SAÍDA:

valor_a_pagar id_do_pedido desabilitar
45809,00 ORDEM-2025-04-11-B71D0E2F5D8C 0
146718,00 ORDEM-2025-04-11-D95EB033CA40 0
146718,00 PEDIDO-2025-04-11-7F04EFA2BB60 0
79318,00 ORDEM-2025-04-10-3F03EAA47686 0
79318,00 ORDEM-2025-04-10-F4A89E2C4A30 0
45809,00 ORDEM-2025-04-08-31BD887341FA 0
SELECT * FROM @SubProductVarKeyValue

SAÍDA:

valor id_var_do_produto pv_key_name_id
novo PROD-VAR-ID-1 PVKN-ID-1
novo PROD-VAR-ID-2 PVKN-ID-1
novo PROD-VAR-ID-5 PVKN-ID-1
novo PROD-VAR-ID-6 PVKN-ID-1
SELECT * FROM @SubProductVarKeyNames

SAÍDA:

pv_key_name_id nome_da_chave
PVKN-ID-1 Doença

Aqui está o exemplo modificado do script que é semelhante ao primeiro fornecido:

DECLARE @user_id VARCHAR(50) = 'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL'; -- FOR TESTING PURPOSES ONLY
DECLARE @status_t TABLE (status VARCHAR(50));
INSERT INTO @status_t VALUES ('PENDING'),('APPROVED'),('PROCESSING')

SELECT
    orders.batch_code, -- FOR DEMONSTRATION PURPOSES ONLY
    oa_prod.nested_data AS nested_prod,
    cnb.amount_to_pay
FROM
    @Orders AS orders
RIGHT OUTER JOIN
    @Payment AS cnb
ON
    orders.order_id = cnb.order_id
LEFT OUTER JOIN
    @StatusRef AS stat_ref
ON
    orders.stat_ref_id = stat_ref.stat_ref_id
CROSS APPLY( -- OR OUTER APPLY
    SELECT
        orders.batch_code,
        orders.order_id,
        prod.prod_name,
        pv_kn.key_name,
        pv_kv.value,
        CASE WHEN
            orders.prod_id IS NOT NULL
        THEN
            prod.disc_price
        WHEN
            orders.prod_var_id IS NOT NULL
        THEN
            prod_var.disc_price
        END AS disc_price,
        orders.quantity
    FROM
        @Product AS prod
    RIGHT OUTER JOIN
        @SubProduct AS prod_var
    ON
        prod.prod_id = prod_var.prod_id
    LEFT OUTER JOIN
        @SubProductVarKeyValue AS pv_kv
    ON
        prod_var.prod_var_id = pv_kv.prod_var_id
    LEFT OUTER JOIN
        @SubProductVarKeyNames AS pv_kn
    ON
        pv_kv.pv_key_name_id = pv_kn.pv_key_name_id
    WHERE       
        prod.prod_id = orders.prod_id
        OR prod_var.prod_var_id = orders.prod_var_id
    FOR JSON PATH,
    INCLUDE_NULL_VALUES
) AS oa_prod(nested_data) -- it's a syntax analyzer lint conflict ONLY
WHERE
    orders.disable = 0
    AND cnb.disable = 0
    AND orders.user_id = @user_id
    AND stat_ref.com_usd_wrds IN (SELECT status FROM @status_t)
ORDER BY
    orders.dt_stamp DESC
    --orders.batch_code ASC -- To prevent batch_code from being separated
FOR JSON PATH,
INCLUDE_NULL_VALUES

Infelizmente, quando embelezo a saída JSON, isso é o que ele gera:

[
  {
    "batch_code": null,
    "nested_prod": [
      {
        "batch_code": null,
        "order_id": "ORDER-2025-04-11-B71D0E2F5D8C",
        "prod_name": "iPhone",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 45809,
        "quantity": 1
      }
    ],
    "amount_to_pay": 45809
  },
  {
    "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
        "order_id": "ORDER-2025-04-11-D95EB033CA40",
        "prod_name": "Samsung",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 40209,
        "quantity": 2
      }
    ],
    "amount_to_pay": 146718
  },
  {
    "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
        "order_id": "ORDER-2025-04-11-7F04EFA2BB60",
        "prod_name": "Nokia",
        "key_name": null,
        "value": null,
        "disc_price": 33150,
        "quantity": 2
      }
    ],
    "amount_to_pay": 146718
  },
  {
    "batch_code": "BGUID-2025-04-10-20239FD2059F",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-10-20239FD2059F",
        "order_id": "ORDER-2025-04-10-3F03EAA47686",
        "prod_name": "Google",
        "key_name": null,
        "value": null,
        "disc_price": 53509,
        "quantity": 1
      }
    ],
    "amount_to_pay": 79318
  },
  {
    "batch_code": "BGUID-2025-04-10-20239FD2059F",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-10-20239FD2059F",
        "order_id": "ORDER-2025-04-10-F4A89E2C4A30",
        "prod_name": "Sony",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 25809,
        "quantity": 1
      }
    ],
    "amount_to_pay": 79318
  },
  {
    "batch_code": null,
    "nested_prod": [
      {
        "batch_code": null,
        "order_id": "ORDER-2025-04-08-31BD887341FA",
        "prod_name": "Lenovo",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 49100,
        "quantity": 1
      }
    ],
    "amount_to_pay": 49100
  }
]

No entanto, preciso que a saída seja algo como isto:

[
  {
    "batch_code": null,
    "nested_prod": [
      {
        "batch_code": null,
        "order_id": "ORDER-2025-04-11-B71D0E2F5D8C",
        "prod_name": "iPhone",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 45809,
        "quantity": 1
      }
    ],
    "amount_to_pay": 45809
  },
  {
    "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
        "order_id": "ORDER-2025-04-11-D95EB033CA40",
        "prod_name": "Samsung",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 40209,
        "quantity": 2
      },
      {
        "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
        "order_id": "ORDER-2025-04-11-7F04EFA2BB60",
        "prod_name": "Nokia",
        "key_name": null,
        "value": null,
        "disc_price": 33150,
        "quantity": 2
      }
    ],
    "amount_to_pay": 146718
  },
  {
    "batch_code": "BGUID-2025-04-10-20239FD2059F",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-10-20239FD2059F",
        "order_id": "ORDER-2025-04-10-3F03EAA47686",
        "prod_name": "Google",
        "key_name": null,
        "value": null,
        "disc_price": 53509,
        "quantity": 1
      },
      {
        "batch_code": "BGUID-2025-04-10-20239FD2059F",
        "order_id": "ORDER-2025-04-10-F4A89E2C4A30",
        "prod_name": "Sony",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 25809,
        "quantity": 1
      }
    ],
    "amount_to_pay": 79318
  },
  {
    "batch_code": null,
    "nested_prod": [
      {
        "batch_code": null,
        "order_id": "ORDER-2025-04-08-31BD887341FA",
        "prod_name": "Lenovo",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 49100,
        "quantity": 1
      }
    ],
    "amount_to_pay": 49100
  }
]

Observação: O amount_to_payfoi pré-calculado no aplicativo cliente. Portanto, ele deve se tornar uma instância única quando batch_codes duplicados forem agrupados.

Os pedidos do usuário podem causar variações na saída JSON desejada mostrada acima.

Alguém está familiarizado com o problema que estou enfrentando?

Na medida do possível, prefiro não implementar a abordagem Common Table Expression (CTE).

sql-server
  • 2 respostas
  • 109 Views
Martin Hope
J. Mini
Asked: 2025-04-12 07:15:22 +0800 CST

Qual abordagem para upserts seguros de simultaneidade é melhor para entradas com valor de tabela se MERGE for proibido?

  • 10

Este artigo clássico sobre segurança de concorrência foi claramente projetado para realizar o upsert de apenas uma linha por vez. Na minha situação, tenho uma entrada com valor de tabela e quero realizar o upsert de cada linha de forma segura em termos de concorrência. Sei que isso nem sempre é possível, mas quero chegar o mais perto possível. MERGEParece uma solução natural, mas desconfio dela e, na verdade, estou em uma situação em que é propensa a bugs . As duas abordagens restantes no artigo de Michael J. Swart são:

  1. Dentro de uma transação com dicas de bloqueio (atualização mais comum)
CREATE PROCEDURE s_AccountDetails_Upsert ( @Email nvarchar(4000), @Etc nvarchar(max) )
AS 
SET XACT_ABORT ON;
BEGIN TRAN
 
  UPDATE TOP (1) dbo.AccountDetails WITH (UPDLOCK, SERIALIZABLE)
     SET Etc = @Etc
   WHERE Email = @Email;
 
  IF (@@ROWCOUNT = 0)
  BEGIN      
      INSERT dbo.AccountDetails ( Email, Etc )
      VALUES ( @Email, @Etc );
  END 
COMMIT
  1. Dentro de uma transação com dicas de bloqueio (inserir mais comum)
CREATE PROCEDURE s_AccountDetails_Upsert ( @Email nvarchar(4000), @Etc nvarchar(max) )
AS 
SET XACT_ABORT ON;
BEGIN TRAN
 
  INSERT dbo.AccountDetails ( Email, Etc )
  SELECT @Email, @Etc
  WHERE NOT EXISTS (
      SELECT *
      FROM dbo.AccountDetails WITH (UPDLOCK, SERIALIZABLE)
      WHERE Email = @Email
  )
 
  IF (@@ROWCOUNT = 0)
  BEGIN      
      UPDATE TOP (1) dbo.AccountDetails
      SET Etc = @Etc
      WHERE Email = @Email;
  END 
COMMIT 

Eu poderia adaptar qualquer uma delas para usar variáveis ​​de tabela (por exemplo, suspeito que IF (@@ROWCOUNT = 0)precise ser totalmente removida), mas o uso de uma entrada com valor de tabela torna óbvio que devemos preferir a primeira ou a segunda solução? Se não, com base em quê a decisão deve ser tomada?

sql-server
  • 2 respostas
  • 424 Views
Prev
Próximo

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve