segunda-feira, 28 de março de 2022

Analysis services still not available for VS2022 - check that before get rid of 2019

 The Analysis services project templates are still not available for VS2022 - check that before get rid of 2019, or keep both versions side by side for getting the best of all. 

Below we can see a screen snapshot from SSIS, which is on the same situation. 



quarta-feira, 17 de novembro de 2021

Fazendo upgrade do Reporting Services (RS) ao expirar prazo de avaliação

 

Após expirar sua versão do Reporting Services você não precisa perder nada ou desinstalar o RS atual, mas se você tentar fazer o upgrade diretamente com o instalador ele vai te bloquear e dizer que não é possível, e que você deve tentar uma nova versão. Para evitar o erro siga os passos a seguir:

- Alterar ou remover programas (Programs and ?Features)

- Localizar o Report Services (Microsoft SQL Server Reporting Services)

- Botão direito > Uninstall/Change

- Selecione Upgrade Edition












Entre com o product key. Se a tua versão instalada já expirou é provável que esta seja a única opção que vai habilitar o Next.

Depois disto você apenas confirma o que precisar e depois testa o funcionamento do RS. 

Observação: Não delete a chave criptográfica mesmo que tenha o arquivo. Se não tiver o arquivo faça o procedimento normalmente porque ele não exige o backup/restore da chave. Somente instalação em novo servidor é que vai exigir a chave se a base de dados, data sources e assinaturas forem originais do servidor anterior. 




sábado, 23 de outubro de 2021

O procedimento espera o parâmetro '@statement' do tipo 'ntext/nchar/nvarchar'.

 Se ao executar um comando no SQL Server Management Studio você obtiver um erro com este título então fique atento para o fato que alguns comandos exigem que você use o prefixo N na frente das strings. Eu não tenho o hábito de usar, mas é fato que isso pode causar alguns problemas como este citado. É raro eu ter problemas com isto, mas quando se trata de SP_EXECUTESQL é melhor ficar atento.

O comando EXEC SP_EXECUTESQL 'STRING A EXECUTAR' pode apresentar o erro "O procedimento espera o parâmetro '@statement' do tipo 'ntext/nchar/nvarchar'."

Se isto ocorrer tente EXEC SP_EXECUTESQL N'STRING A EXECUTAR'. Repare que acrescentamos o N antes da String a ser executada. Este é modelo indicado nos manuais o tempo todo, e por isso não é comum ver este erro quem segue o manual à risca.

Bom trabalho.


sábado, 14 de agosto de 2021

SQL Server error Could not obtain information about Windows NT group/user

Vários jobs estavam apresentando o erro abaixo porque a empresa fez uma mudança de domínio do AD e o usuário que havia sido usado para criar os jobs fazia parte do antigo domínio. É o mesmo problema que ocorre quando se exclui um usuário do AD e recria com o mesmo nome. O usuário existe mas não é o mesmo. Neste caso ele realmente ainda existe, mas o domínio está fora de uso ou de alcance, sem responder às requisições de permissões (ou similar). Não adiantou trocar o owner do job diretamente na interface, apesar de isso parecer mais que suficiente. Somente depois que peguei uma dica do mestre Pinal Dave é que a coisa começou a melhorar, embora não tenha sido suficiente para tudo. 

Outra ação que fiz foi, segundo uma fonte que agora não lembro, fazer um Detach e Attach usando o SA user database para refazer todos os logons (se é que isso serviu, mas eu fiz).

Message: The job failed.  Unable to determine if the owner (domain\user) of job <job name> has server access (reason: Could not obtain information about Windows NT group/user 'domain\user', error code 0x6fc. [SQLSTATE 42000] (Error 15404)).  NOTE: Failed to notify 'Alexandre Paiva' via email.

USE MSDB
GO
UPDATE sysssispackages
SET ownersid = SUSER_SID('sa')
WHERE NAME = 'Name Of Maint Plan'

No meu caso, como tudo estava quebrado, eu não usei o WHERE. Que luxo poder rodar um Update sem Where. Tome cuidado.


Fonte: https://blog.sqlauthority.com/2018/08/20/sql-server-fix-error-the-job-failed-unable-to-determine-if-the-owner-domainuser-of-job-job_name-has-server-access/

SQL Server Logon to server failed - ConnLogJobHistory

Dentre os vários possíveis erros para esta mensagem uma delas que acabei tendo que enfrentar esta semana foi que o @@ServerName estava apontando para o antigo nome do servidor que foi virtualizado. Após horas de investigação e muitas tentativas de outras soluções finalmente cheguei à causa raiz do problema, o bendito server name desatualizado.

Message [382] Logon to server 'servername' failed (ConnLogJobHistory)

O SQLServerAgent tentava se autenticar ou algo parecido no nome antigo. Como isto não era mais possível os Jobs simplesmente não executavam. Dava o start, mas nada, até cair por timeout

Após aplicar os comandos a seguir foi necessário apenas reiniciar os serviços, deconectar da instância e reconectar no Management Studio.

EXEC sp_dropserver '<old_name>'; GO EXEC sp_addserver '<new_name>', local; GO


The jobs are running. Shout to the Lord.


Fonte: https://docs.microsoft.com/pt-br/sql/database-engine/install-windows/rename-a-computer-that-hosts-a-stand-alone-instance-of-sql-server?view=sql-server-ver15

sexta-feira, 30 de julho de 2021

Erro ao criar assinatura no Report Server

Se você está com problemas ao criar assinatura para os relatórios no Reporting Server uma permissão pode resolver o problema. Inclua a conta do ReportingServices na role SysAdmin.

Depois de 2 dias pesquisando sobre o problema eu achei um paper da MS sobre a versão 2012 que resolveu meu problema.

Security

 NT SERVICE\SQLServerReportingServices > Roles > sysadmin


Fonte: KB2926089-FIX: erro ao criar novas assinaturas de relatório após a aplicação do CU7 ou do CU8 para SQL Server 2012 SP1 (microsoft.com)

quinta-feira, 1 de abril de 2021

SSMS 18 Errors

 Since I've changed from SSMS 17 to 18 my life becomes harder. It's a shame to get a hole new tool, based on a superb successful previous version and have bad times all the time. Yes, I love the improvements, but I missed very hard the absence of the Debug feature inside SSMS 18. 

But this is not the only question: frequently I have some problem wich the solution is to reinstall the older version to fix it. Now I've the Integration Service stop responding on a server after I upgraded the SSMS to 18.x. The only solution I coud find googling was: downgrade your version of SSMS to 17 and be happy.

What will I do?


Donwloading SSMS 17 in progress... (21%)


Shame on you Microsoft, my beloved Microsoft.

segunda-feira, 27 de abril de 2020

Não é possível restaurar um backup pequeno mesmo quando há espaço em disco

Se ao tentar restaurar um backup suficientemente pequeno para o espaço disponível em disco, mas que o SQL insiste em informar que não há espaço em disco, tente os comandos a seguir para reduzir os espaços alocados mas não utilizados do banco de dados e do arquivo de log. Em geral é o arquivo de Log que causa tais problemas, em especial nos bancos de muita transação. Por isso o exemplo abaixo vai encolher, ou shrink, o arquivo para o tamanho real (ou quase, já que podemos deixar uma margem reservada para ganho de desempenho ao precisar de novo espaço).

ALTER DATABASE <db_name>  SET RECOVERY SIMPLE;
GO
DBCC SHRINKFILE(<db_name>_log, 200);
GO
ALTER DATABASE <db_name> SET RECOVERY FULL;
GO

<db_name> = busque pelo nome lógico do banco nas propriedades > arquivos se o comando informar que não localizou o arquivo.

Também é possível fazer isso pela interface gráfica, mas o comando parece não funcionar, ou não executar imediatamente (deferred basis?). Na linha de comando sempre funcionou.

Para mais detalhes sobre o comando consulte a documentação.

Frases do erro: Restore of database failed. There is insufficient free space on disk.

quarta-feira, 19 de fevereiro de 2020

Selecionando e deletando registro duplicados


WITH TableWithRowID AS
(
 SELECT ROW_NUMBER() OVER (PARTITION BY ORDER BY ) AS RowID, 
  FROM
)
DELETE o
FROM TableWithRowID o
WHERE RowID > 1



Fonte:
https://www.mssqltips.com/sqlservertip/4486/find-and-remove-duplicate-rows-from-a-sql-server-table/

sexta-feira, 2 de agosto de 2019

Transferindo Report Server entre servidores

Se seu objetivo é transferir um report server de um servidor para outro, em especial entre versões atualizadas do SQL Server, é possível fazer com pouco esforço, de forma muito automatizada, usando uma ferramenta do próprio SQL Server Reporting Server (SSRS), com interface gráfica ou via console.

Na pasta de instalação do SSRS é possível encontrar a RS.exe, que faz o trabalho pesado de migrar relatórios e itens relacionados (pastas, data sources, etc). Em versões anteriores este .exe ficava na pasta Tools do SQL Server, mas agora a MS já melhorou isto alocando-o dentro da pasta do SSRS.

No link a seguir tem a RSMigrationTool com interface gráfica. Esta ferramenta também pode ser chamada via console.

https://www.microsoft.com/en-us/download/details.aspx?id=29560
Vídeo: https://www.youtube.com/watch?v=ZL8FqCcxBsU

A seguir temos as instruções para usar o RS.exe (sem firula, só console):
https://docs.microsoft.com/en-us/sql/reporting-services/tools/script-with-the-rs-exe-utility-and-the-web-service?view=sql-server-2017

Atenção: Lembre-se de conferir se o SQL Agent está rodando no servidor de destino para garantir que os jobs e agendamentos sejam executados.

Será necessário baixar um arquivo com as configurações do que deve ser baixado e que será usado como parâmetro no RS.exe: ssrs_migration.rss.
https://docs.microsoft.com/en-us/sql/reporting-services/tools/sample-reporting-services-rs-exe-script-to-copy-content-between-report-servers?view=sql-server-2017

Para executar na linha de comando, com o arquivo .rss baixado do github, segue um exemplo de sintaxe. Estou reproduzindo aqui apenas para facilitar, mas tem outros na pagína do link acima:
rs.exe -i ssrs_migration.rss -e Mgmt2010 -s https:///ReportServer -u Domain\User -p password -v ts="https:///reportserver" -v tu="Domínio\ContaUsuário" -v tp="" -v security="True"

A conta usada deve ter o mínimo de permissões para acessar o endpoint ReportServer de cada servidor. Normalmente é uma conta de administração de servidor ou com tais permissões.

Exemplo de um comando usado recentemente aqui na empresa (informações de segurança foram retiradas):
rs.exe -i ssrs_migration.rss -e Mgmt2010 -s http://servername_origem/reportserver -u dominio\usuario -p <senha> -v ts="http://servername_destino/reportserver" -v tu="dominio\usuario" -v tp="<senha>" -v security="True"

Você verá a mensagem: You can cancel the script after step 1 if you do not want to start the actual migration. Significa que o RS executa 2 fases: a primeira é um levantamento, e pode ser cancelada logo que concluída. Tudo que o RS conseguir acessar será listado. Se estiver satisfeito com o que foi listado, pressione ENTER para executar a segunda fase, a da transferência.


Verifique se tudo foi migrado de acordo.

Atualize os Data Sources se necessário, pois eles apontam para o mesmo lugar de antes, então se você migrou não só o Report Service, mas também o Database Server, terá que atualizar.

A parte de segurançao poder ser a mais difícil de migra (-v security="True"), então sempre confira se os usuários terão acesso ou se será necessário conceder novamente as permissões. Eu prefiro usar Autenticação integrada nos reports para evitar estas configs.

terça-feira, 23 de janeiro de 2018

Migrating SQL Server Profiler templates

After some hours trying to migrate a SQL Server Profiler 2008R2 template to 2014 I came to a result: It can´t be done directly inside the Profiler (not in a intuitive way). When you choose the destination version the list of profiles change and you lose the one you want to migrate. It seems to be not possible to migrate, even though you can find some steps in our beloved StackOverflow to do it. And, on that same site exists a tip which tells us to just copy and paste the .tdf files from one folder version to another, and voilá, we gotcha!

Well, that is the simplest and the best tip I´ve used to migrate templates.

Copy files from one version to another, using the template folder on:

%AppData%\Microsoft\SQL Profiler\\Templates\Microsoft SQL Server\

Good job!

quarta-feira, 26 de julho de 2017

Set vs Select para atribuir valores

Vejam neste artigo da SQLMagazine a importante diferença entre o uso do SET e do SELECT. Há coisas quase irrelevantes, mas há algumas pérolas no texto, como (1) a parte da subconsulta que retorna múltiplos valores, e (2) da atribuição de NULL.

http://www.sqlmagazine.com.br/artigos/sqlserver/07_SETxSELECT.asp (By Edison Costa)

Vale ressaltar que o erro abaixo:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

Só ocorre pela forma da atribuição, e não porque foi usado o SET ou o SELECT.
Assim não dá erro:
SELECT @Variavel = from

Mas assim o erro acontece quando a subquery retorna mais de um resultado:
@Variavel = (subquery)

O caso em que não há o erro o resultado é não-determinístico, pois não sabemos qual valor dos retornados o SQL vai escolher para popular a @variavel.

terça-feira, 13 de junho de 2017

Two must read articles about Oracle RowNum

When thinking about rownum pseudocolumn for getting pages of record we have to read some articles to remember the issues about the way rownum works.

There are thousands of articles about, so, it's healthy to have a good backup of good articles in our pocket to avoid long time search:

http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html

https://explainextended.com/2009/05/06/oracle-row_number-vs-rownum/

If you know some better articles about rownum please share with us!

quarta-feira, 7 de junho de 2017

[SSRS] Relatório zebrado usando agrupamento

Ao usar listagens comuns no Report Server temos a boa e velha fórmula
= iif(RowNumber(Nothing) mod 2=0, "Cordesejada", "CorAlternativa")
para definir a alternância das cores das linhas, criando o efeito "zebrado".

Mas para os casos de relatórios que possuem agrupamentos e não é possível (ou facilmente) definir a ordem de renderização ou de enumeração das linhas e colunas, então a fórmula tradicional acima não funciona, ou pelo menos, não tem garantia de funcionar. Minha experiência é que não funciona mesmo quando tem agrupamento.

Para isto existe outra forma de configurar a alternância, que em meus testes deu certo até agora...

=iif(RunningValue(Fields![rowgroupfield_name].Value[.ToString],CountDistinct,Nothing) Mod 2,"Gainsboro", "White")

Há de se ter cuidado com agrupamentos que não preenchem todos os intervalos, pois podem causar problemas e confundir a fórmula, mas eu ainda não tive este problema. Há vários relatos deste problema nas discussões na Internet, inclusive para rotinas customizadas usadas no Report Code section ou com assemblies.

Fonte: https://stackoverflow.com/questions/44376/add-alternating-row-color-to-sql-server-reporting-services-report/6777983#6777983
Thanks to @ahmad.

quinta-feira, 18 de maio de 2017

RAISERROR, Transaction outcome and execution flow

Remember that when using RAISERROR inside procedures or triggers it does:
- not issue a rollback
- not interrupt the execution

For that results, when desired, use a ROLLBACK command explicitly, and a RETURN to quit from the routine. Do not misunderstand this concepts because it is so easy to think the RAISERROR will interrupt both the transaction and the execution flow.

For more detailed situations, which can apply to your case, browse on Microsoft Technet or MSDN, and google for more informations from the experts on the Internet.

Example:
Using a trigger to show the concept, we can issue any DML statements, receive an error message, and, anyway, the statements will work. No interruption. No rollback after raiserror.

CREATE TRIGGER dbo.trg_dml_testtrans
   ON  dbo.testtrans
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

print '@@trancount: ' + cast( @@trancount as varchar);

    -- Insert statements for trigger here
    raiserror('raising an error...', 16, 10);
    
print '@@trancount: ' + cast( @@trancount as varchar); 
END

insert testtrans (cola, colb) values (1, 'aaa');
insert testtrans (cola, colb) values (2, 'bbb');
update testtrans set colb='ccc' where cola=2
delete testtrans where cola=2

Each of above statements will get the errors message, even though working as expected. See one message example below, for delete statement:

@@trancount: 1
Msg 50000, Level 16, State 10, Procedure trg_dml_testtrans, Line 18
raising an error...
@@trancount: 1

Going further, the following commands show us that the delete statement (and so the insert and update) starts an implicit transaction (or automatic transaction) when executing, then commits on  after successfuly perform (auto commit). That´s because you did not see any transaction statements in the example.

print '@@trancount: ' + cast( @@trancount as varchar);
delete testtrans where cola=3
print '@@trancount: ' + cast( @@trancount as varchar);

@@trancount: 0
@@trancount: 1
Msg 50000, Level 16, State 10, Procedure trg_dml_testtrans, Line 18
raising an error...
@@trancount: 1

(1 row(s) affected)
@@trancount: 0

Try to change the trigger to issue a rollback in some condition and see for yourself how funny is to work with databases. I will give you another example:

ALTER TRIGGER [dbo].[trg_dml_testtrans]
   ON  [dbo].[TestTrans]
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
   SET NOCOUNT ON;

   print '@@trancount: ' + cast( @@trancount as varchar);

   if (select colb from inserted) = 'zzz'
   begin
       raiserror('raising an error...', 16, 10);
       rollback;
       --use RETURN here to get out immediately
   end
    
   print '@@trancount: ' + cast( @@trancount as varchar); 
END

insert testtrans (cola, colb) values (7, 'zzz');

@@trancount: 1
Msg 50000, Level 16, State 10, Procedure trg_dml_testtrans, Line 19
raising an error...
@@trancount: 0
Msg 3609, Level 16, State 1, Line 2
The transaction ended in the trigger. The batch has been aborted.

This means that the 'zzz' won't be inserted.

That's all for now, folks!

quinta-feira, 23 de março de 2017

The Autoclose effect

A valuable and simple tip for setting the autoclose property of a database and get more performance among the connections up and down. It´s in PT-BR, but you know the google translate, don't you?

https://www.dirceuresende.com/blog/sql-server-sua-instancia-esta-constantemente-com-mensagens-starting-up-database-e-databases-in-recovery-conheca-o-auto-close/

quarta-feira, 15 de março de 2017

How to change and query the retention period of CDC cleanup job [SQLSERVER]

We can use a simple way to manage the retention period of CDC cleanup routine.
Be sure to set the database you want to change because the stored procedure use the current database.
I set up 90 days retention, using 90*24*60 minutes as argument, but you should ensure your database growth will fit in you available space. Keep track of you database size for a few days before go on vacation.

use
go

SELECT DB_ID(), [retention]
  FROM [msdb].[dbo].[cdc_jobs]
  WHERE [database_id] = DB_ID()
  AND [job_type] = 'cleanup'

sp_cdc_change_job @job_type='cleanup', @retention=129600
go

SELECT DB_ID(), [retention]
  FROM [msdb].[dbo].[cdc_jobs]
  WHERE [database_id] = DB_ID()
  AND [job_type] = 'cleanup'


Source: http://sqlblog.com/blogs/allen_white/archive/2012/03/07/set-and-verify-the-retention-value-for-change-data-capture.aspx

 Anothe good tip in the source is this query, wich brings more information about CDC jobs settings:
select * from msdb.dbo.cdc_jobs

There are some more issues about this topic in the source, but for me the above content was enough to make my day. Hence, that´s all for now, folks! 

Good queries!

sexta-feira, 3 de março de 2017

Commit and Rollback are not simmetrical about @@trancount

Source: https://www.codeproject.com/Articles/4451/SQL-Server-Transactions-and-Error-Handling

That´s why it's so important to check @@trancount or track the rollbacks inside nested transactions, avoiding errors with rollback without transaction related.


Figure 1: A COMMIT always balances a BEGIN TRANSACTION by reducing the transaction count by one.


Figure 2: A single ROLLBACK always rolls back the entire transaction.

segunda-feira, 11 de julho de 2016

Recuperando TOP N linhas de uma consulta relacionada com APPLY

Neste link tem um exemplo muito útil para as situações em que é preciso recuperar as n linhas de uma tabela relacionada para cada registro da tabela mestre, usando o CROSS APPLY (ou OUTER APPLY, quando for o caso).

http://stackoverflow.com/a/2791907/3817131

Cuidado para não cair na armadilha do
SELECT * 
FROM TABLE_A AS a
LEFT JOIN (SELECT TOP 8 id, field1, field2
           FROM TABLE_b) AS b
    ON a.id = b.id
 
Pois este caso traz um jon com as TOP n *GERAL* da tabela B, não de cada linha do lado esquerdo do relacionamento.
Mesmo quando se tenta usar um JOIN/WHERE na subquery pegando a chave da tabela mestre para relacionar como parâmetro é preciso atentar para a sintaxe e para os resultados retornados.
Em alguns casos é preciso fazer uma subquery para  selecionar o resultado de um subquery mais interna.

O APPLY é uma solução elegante do TSQL e de bom desempenho, mas não é ANSI.


sexta-feira, 17 de junho de 2016

Excluindo registros repetidos


No link https://support.microsoft.com/pt-br/kb/139444 onde a Microsoft mostra como eliminar duplicidades de tuplas, podemos acrescentar outra técnica bem conhecida no exemplo, usando a própria t1. A técnica da holdkey table onde se exclui todos os registros e depois precisa reincluir pode não ser a opção ideal em bancos muito grandes, com uma tabela cheia de chaves, constraints, triggers, identity, etc.

Há uma solução padrão que usamos sem precisar reinserir os códigos distinct, pois a exclusão é feita sem precisar remover as multiplicidades, mas somente excluindo as n-1 ocorrências. O requisito é ter uma coluna que seja pelo menos uma chave candidata para fazer a exclusão da linha que não será eliminada.

ALTER TABLE t1 ADD id_1 int identity(1,1) not null;  --Criando a chave candidata, já que t1 não tem uma, e que pode ser temporária apenas para a exclusão

delete t1
where
    col2 in (SELECT col2 FROM t1 GROUP BY col2 HAVING count(*) > 1)
    and NOT id_1 in (SELECT MIN(ID_1) FROM t1 GROUP BY col2 HAVING count(*) > 1)

Em caso de múltiplas colunas, onde a cláusula IN não permite mais que uma coluna***, podemos concatenar

Exemplo real, utilizado recentemente em um cliente:
delete from dias_leitura
where codigo_cliente+cast(subcodigo as varchar) in
  (select codigo_cliente+cast(subcodigo as varchar) from dias_leitura
   group by codigo_cliente + cast(subcodigo as varchar)
   having Count(*)>1)
and not codigo in
  (select Min(codigo) from dias_leitura
   group by  codigo_cliente+cast(subcodigo as varchar)
   having Count(*)>1)

*** Isto é permitido no Oracle:  WHERE col1, col2 in (select col1, col2 from t1)...