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 / user-23485

Ian Kemp's questions

Martin Hope
Ian Kemp
Asked: 2023-04-01 00:17:26 +0800 CST

É possível atualizar uma tabela existente em uma única instrução, usando a saída de uma instrução MERGE?

  • 6

Sei que posso conseguir isso de várias maneiras - essa é uma questão puramente acadêmica para ver se é possível fazer isso em uma única instrução, a fim de aprofundar meus conhecimentos de SQL.

Estamos dividindo uma tabela antiga e larga em duas tabelas mais estreitas, uma pai e uma filha:

create table WorkTable
     ( ParentId     int             null
     , ChildId      int         not null
     , ParentField1 varchar(50) not null )

create table ParentTable
     ( Id     int         not null primary key identity
     , Field1 varchar(50) not null )

create table ChildTable
     ( Id       int not null primary key identity
     , ParentId int not null foreign key references ParentTable ( Id ) )

WorkTablecontém vários registros da tabela original - o ID dessa tabela que queremos usar como o ID na tabela filho (via identity_insert) e um campo dessa tabela que realmente queremos definir no pai. Para cada linha em WorkTable, portanto, teremos 1 linha em ParentTablee outra em ChildTable.

Agora vou preencher ParentTablee também obter os IDs de seus registros recém-inserido para a inserção subsequente em ChildTable:

declare @IdsMap table
      ( ParentId int not null
      , ChildId  int not null )

merge ParentTable dst
using (
select ChildId
     , ParentField1
  from WorkTable
) src on 1 = 0
when not matched by target then
insert
     ( Field1 )
values
     ( src.ParentField1 )
output inserted.Id as [ParentId]
     , src.ChildId -- can't do this with a standard INSERT...OUTPUT, hence the use of MERGE
  into @IdsMap
;

update wkt
   set wkt.ParentId = ids.ParentId 
  from WorkTable wkt
           join
       @IdsMap   ids on ids.ChildId = wkt.ChildId

Isso funciona, mas é feio. Eu preferiria muito mais se pudesse simplificá-lo em uma instrução, em que os IDs inseridos de ParentTablesão atualizados diretamente de volta Worktable- removendo assim a necessidade da @IdsMaptabela var que existe apenas para realizar essa atualização.

Achei que poderia conseguir isso usando o mergeDML aninhado:

update wkt
   set wkt.ParentId = cte.ParentId
  from WorkTable wkt
           join
(
merge ParentTable dst
using (
select ChildId
     , ParentField1
  from WorkTable
) src on 1 = 0
when not matched by target then
insert
     ( Field1 )
values
     ( src.ParentField1 )
output inserted.Id as [ParentId]
     , src.ChildId
) cte on cte.ChildId = wkt.ChildId

mas o MSSQL diz que não:

A nested INSERT, UPDATE, DELETE, or MERGE statement is not
allowed on either side of a JOIN or APPLY operator.

O DML aninhado dentro de um CTE também falha:

;with cte as
(
select *
  from
(
merge ParentTable dst
using (
select ChildId
     , ParentField1
  from WorkTable
) src on 1 = 0
when not matched by target then
insert
     ( Field1 )
values
     ( src.ParentField1 )
output inserted.Id as [ParentId]
     , src.ChildId
) _
)
update wkt
   set wkt.ParentId = cte.ParentId
  from WorkTable wkt
           join
                 cte on cte.ChildId = wkt.ChildId
A nested INSERT, UPDATE, DELETE, or MERGE statement is not allowed in a SELECT
statement that is not the immediate source of rows for an INSERT statement.

Existe alguma maneira de conseguir o que estou procurando?

sql-server
  • 2 respostas
  • 168 Views
Martin Hope
Ian Kemp
Asked: 2021-07-31 01:51:29 +0800 CST

Existe alguma implicação de desempenho de usar varchar(max) sobre varchar(n) em cast/convert?

  • 1

Considere a seguinte expressão, que trunca ( não arredonda ) os milissegundos de um valor de data e hora:

declare @now datetime2 = sysdatetime();
select @now;
select convert(datetime2, convert(varchar(20), @now, 120));

-- Output
2021-07-30 09:38:33.5566666
2021-07-30 09:38:33.0000000

Observe o varchar(20). Eu não gosto desse valor de comprimento específico porque se eu mudar meus tipos de dados, pode haver perda de dados:

declare @now datetimeoffset = sysdatetimeoffset() at time zone 'Pacific Standard Time';
select @now;
select convert(datetimeoffset, convert(varchar(20), @now, 120));

-- Output
2021-07-30 02:39:12.7200000 -07:00
2021-07-30 02:39:12.0000000 +00:00 -- oops, we lost the time zone too!

Por isso, prefiro usar o seguinte:

declare @now datetimeoffset = sysdatetimeoffset() at time zone 'Pacific Standard Time';
select @now;
select convert(datetimeoffset, convert(varchar(max), @now, 120)); -- note MAX not N

-- Output
2021-07-30 02:41:16.4566666 -07:00
2021-07-30 02:41:16.0000000 -07:00

Minha pergunta é: existe algum tipo de implicação significativa de desempenho no uso de varchar(max)over varchar(N)- incluindo, mas não limitado a alocações de memória?

Estou ciente de que há implicações para o desempenho da consulta se usar (max)tipos de dados sobre (N)tipos de dados em predicados , mas em meus exemplos específicos não estou fazendo isso - apenas alocando os varchars e jogando-os fora depois de convertê-los de volta para o tipo de dados desejado.

sql-server performance
  • 1 respostas
  • 219 Views
Martin Hope
Ian Kemp
Asked: 2019-05-07 21:11:11 +0800 CST

Tentando reparar o repositório de consultas, mas sp_query_store_consistency_check não existe

  • 3

O repositório de consultas em nosso banco de dados SQL Server 2016 Standard (SP2 CU6) entrou em ERRORestado e agora estamos tentando recuperá-lo online. Todos os artigos que vi sobre solução de problemas de QS (por exemplo , este e até mesmo os próprios documentos da Microsoft ) sugerem fazer o seguinte:

ALTER DATABASE [QDS] SET QUERY_STORE = OFF
exec [QDS].dbo.sp_query_store_consistency_check
ALTER DATABASE [QDS] SET QUERY_STORE = ON
ALTER DATABASE [QDS] SET QUERY_STORE (OPERATION_MODE = READ_WRITE)

Mas o procedimento sp_query_store_consistency_checknão parece existir de forma alguma em nossa instância. O que estamos perdendo?

sql-server sql-server-2016
  • 1 respostas
  • 495 Views
Martin Hope
Ian Kemp
Asked: 2016-03-23 04:13:03 +0800 CST

O tipo de dados da coluna de ida e volta faz com que o tamanho da tabela cresça

  • 3

Tabela LogCount:

Column1 int       not null
Column2 int       not null
Column3 int       not null
[Date]  datetime  not null
[Count] float(53) not null

Esta tabela contém aproximadamente 86 milhões de linhas e possui os seguintes índices:

alter table LogCount add constraint PK_LogCount_Id primary key clustered 
( [Date], Column1, Column2, Column3 )
go
create nonclustered index IX_Column2_Date on LogCount ( Column2, [Date] )
include ( [Count] )
go

sp_spaceuseddá o seguinte:

name        rows        reserved    data        index_size  unused  
LogCount    85800181    8089216 KB  4226664 KB  3860968 KB  1584 KB

A Countcoluna não armazena e nunca armazenará números de ponto flutuante, apenas inteiros, então mudei para um smallintque (eu esperava) economizará 6 bytes por linha ( float(53)= 8 bytes, smallint= 2 bytes):

drop index LogCount.IX_Column2_Date
go
alter table LogCount alter column [Count] smallint not null
go
create nonclustered index IX_Column2_Date on LogCount ( Column2, [Date] )
include ( [Count] )
go

Então eu recorri sp_spaceused:

name        rows        reserved    data        index_size  unused
LogCount    85800181    7670848 KB  5255528 KB  2414496 KB  824 KB

Como esperado, o tamanho do índice diminuiu drasticamente, mas o tamanho dos dados aumentou em um gigabyte!

Em seguida, executei novamente a instrução drop/alter/create acima, mas usando int(4 bytes) e obtive o seguinte resultado:

name        rows        reserved    data        index_size  unused
LogCount    85800181    7848032 KB  5255528 KB  2591688 KB  816 KB

Então eu tentei float(1)(também 4 bytes):

name        rows        reserved    data        index_size  unused
LogCount    85800181    7848016 KB  5255528 KB  2591672 KB  816 KB

Finalmente voltei ao original float(53):

name        rows        reserved    data        index_size  unused
LogCount    85800181    10680584 KB 7726896 KB  2952464 KB  1224 KB

Em comparação com o original, o tamanho dos dados aumentou em aproximadamente 3,3 GB (quase dobrou), enquanto o tamanho do índice diminuiu em aproximadamente 900 MB.

Um colega sugeriu que o culpado poderia ser que o MSSQL está alocando páginas adicionais para a alter columninstrução e não as liberando depois, então também tentei executar dbcc shrinkdatabaseapós cada etapa, mas os resultados foram os mesmos.

Então minhas perguntas:

  1. Por que alterar uma coluna de um tipo de dados maior para um menor faz com que mais espaço de dados seja usado?
  2. é sp_spaceusedconfiável? Se não, o que devo usar em vez disso? Se não houver uma opção melhor, como determinar se a alteração do tipo de dados de uma coluna terá um efeito positivo ou negativo no uso do espaço em disco?
sql-server sql-server-2014
  • 2 respostas
  • 139 Views
Martin Hope
Ian Kemp
Asked: 2013-05-08 04:05:45 +0800 CST

Ao executar uma transação entre bancos de dados, em qual(is) log(s) de transação as informações são armazenadas?

  • 9

Dado o seguinte trecho:

-- error checking omitted for brevity
begin tran

exec database1..my_stored_procedure
exec database2..my_other_stored_procedure

if (@@error <> 0)
  rollback

commit

Em qual(is) log(s) de transações do banco de dados as informações transacionais serão inseridas?

Eu esperaria que ambos os logs obtivessem todos os dados, já que não faria sentido se você tentasse reproduzir database1o log de transações e isso afetasse apenas aquele banco de dados. Eu também esperaria que você não conseguisse reproduzir database1o log de transações em um servidor onde database2não estava presente e vice-versa.

.. mas estou aberto a correções!

sql-server sql-server-2008-r2
  • 1 respostas
  • 1807 Views

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