domingo, 7 de agosto de 2016

SQL Server Azure - Query retornando data e hora ajustada com o fuso horário

Para quem está usando SQL Server Azure (funciona também com instância local), segue dica de um query que retorna o horário ajustado de acordo com a timezone informada no formato float.

No exemplo ultilizaremos a timezone -3:

declare @HorDif float = -3
select DATEADD(HH, @HorDif, GETUTCDATE ()) as Resultado




SQL Server - Controlar ID de autoincremento (Alternativa ao autoinc do SQL)

Se você precisa controlar suas IDs (identidade, identity, autoinc), segue uma dica de como fazer isso sem dar locks em tabelas, o que seria um grande problema de desempenho.

1 - Crie a tabela que armazenará os últimos IDs usados:

CREATE TABLE [dbo].[IDs]
(
    IDNom nvarchar(255) NOT NULL,
    IDUlt int NULL,
    CONSTRAINT [PK_tblIDs] PRIMARY KEY CLUSTERED
    (
        [IDNom] ASC
    ) WITH
    (
        PAD_INDEX = OFF
        , STATISTICS_NORECOMPUTE = OFF
        , IGNORE_DUP_KEY = OFF
        , ALLOW_ROW_LOCKS = ON
        , ALLOW_PAGE_LOCKS = ON
        , FILLFACTOR = 100
    )
);
GO

2 Crie a StoredProcedure que vai retornar o novo ID a cada solicitação e registrar seu uso na tabela anterior (SP criada por Max Vernon e Mike Defehr e fiz algumas alterações):

CREATE PROCEDURE [dbo].[ProxID](
    @IDName nvarchar(255)
)
AS
BEGIN

    DECLARE @Retry int;
    DECLARE @EN int, @ES int, @ET int;
    SET @Retry = 5;
    DECLARE @NewID int;
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    SET NOCOUNT ON;
    WHILE @Retry > 0
    BEGIN
        BEGIN TRY
            UPDATE dbo.IDs
            SET @NewID = IDUlt = IDUlt + 1
            WHERE IDNom = @IDName;

            IF @NewID IS NULL
            BEGIN
                SET @NewID = 1;
                INSERT INTO IDs (IDNom, IDUlt) VALUES (@IDName, @NewID);
            END
            SET @Retry = -2; /* no need to retry since the operation completed */
        END TRY
        BEGIN CATCH
            IF (ERROR_NUMBER() = 1205) /* DEADLOCK */
                SET @Retry = @Retry - 1;
            ELSE
                BEGIN
                SET @Retry = -1;
                SET @EN = ERROR_NUMBER();
                SET @ES = ERROR_SEVERITY();
                SET @ET = ERROR_STATE()
                RAISERROR (@EN,@ES,@ET);
                END
        END CATCH
    END
    IF @Retry = 0 /* must have deadlock'd 5 times. */
    BEGIN
        SET @EN = 1205;
        SET @ES = 13;
        SET @ET = 1
        RAISERROR (@EN,@ES,@ET);
    END
    ELSE
        SELECT @NewID AS NovoID;
END
GO

Pronto!

Agora é só usar a SP passando como parâmetro um nome qualquer (no meu caso uso o nome da tabela).
Se não existir, a SP cria automaticamente e retorna o valor 1.
Se já existir ela retorna o novo valor na sequencia.

Exemplo:

Oracle - Listar datas do mês

 select TRUNC(SYSDATE)  + level - 1 dt from   dual connect by level <= (   LAST_DAY(SYSDATE) - TRUNC(SYSDATE) + 1 )