54
Dataserver SQL Server

Dataserver SQL Server - sanderleisilveira.com.br · Introdução Existem diferenças entre DB PROGRESS e DB SQL Server O desenvolvedor deve ter estas diferenças em mente quando está

  • Upload
    vomien

  • View
    257

  • Download
    1

Embed Size (px)

Citation preview

Dataserver SQL Server

Introdução

Existem diferenças entre DB PROGRESS e DB SQL Server

O desenvolvedor deve ter estas diferenças em mente

quando está construindo seus programas.

É preciso saber para qual(is) Data Source(s) o programa está

sendo construído.

Arquitetura DataServer

Progress Application

Progress Enterprise DataServer

for SQL Server

ODBC Driver Manager

ODBC

Driver

ODBC

Driver

DATA SOURCE

DATA Source Manager

DATA SOURCE

DATA Source Manager

Funcionamento do DataServer

SQL SERVER

O usuário executa um

aplicativo Progress

O DataServer faz a tradução

o comando Progress para

SQL

ODBC API

O Data Source recebe

a sentença SQL

O Data Source Manager

manda para o SQL Server

e retorna o resultado

O progress mostra

o resultado.

Funcionamento do DataServer

SQL SERVER

FOR EACH customer:

Display name.

End.

SELECT name

FROM customer.

ODBC API

SELECT name

FROM customer.

‘João’

‘Maria’

‘José’

Nome

--------------------

‘João’

‘Maria’

‘José’

Schema Holder

Progress Schema

Holder

-----------------------

Cust-num – Integer

Name – Character

Max_credit - Decimal

DATA SOURCE

DATA DEFINITIONS

--------------------------

Cust_num – Int

Name – Char

Max_credit - decimal

• Schema Holder tem informações sobre os objetos do Data

Sources MSS

• Progress acessa apenas na compilação e no inicio do Run-

Time (Schema Caching)

Configuração Básica

Local DataServer

PROGRESS CLIENT

DATASERVER

ODBC DRIVER

DATA-SOURCE CLIENT SOFTWARE

SCHEMA

HOLDER

DATA

SOURCE

CLIENT

SCHEMA HOLDER

PROGRESS CLIENT

DATASERVER

ODBC DRIVER

DATA-SOURCE SOFTWARE

Progress

Client

CLIENT

SQL

SERVER

SERVER Progress Enterprise

Dataserver

Configuração Básica

Remote DataServer

Objetos PROGRESS e Objetos SQL Server

O dataserver suporta sequências através de

Stored Procedures nativasSequences

DefaultInitial Value

Foreign KeyNonunique Index

Primary KeyUnique Index

IndexIndex

RowRecord

ColumnField

TableTable/File

SQL SERVERPROGRESS

Considerações Gerais

Cada tipo suportado pelo Dataserver tem pelo menos um

equivalente no Progress

TinyintLogical

IntegerInteger

DecimalDecimal

DatetimeDate

VarcharCharacter

SQL SERVERPROGRESS

Raw Text

Tipos de Dados

Número máximo de atributos por tabela 1024

Número máximo de índices por tabela 249

Número máximo de atributos num índice 16

Soma colunas que compõem o índice 900 bytes

Tamanho máximo para campos Caracter x(8000)

Campos Decimal 28 dígitos

Campos Integer 9 dígitos

Campos Datetime de 01/01/1753 a 31/12/9999

Limitações

Além das validações existentes para Oracle:

Homologação de dicionário será realizada pelo DWB-DDD

através da opção ADF -> Magnus 97 -> Auditoria DataServer.

Valida o tamanho dos índices verificando a possibilidade de

ultrapassar o tamanho máximo de 400 bytes para índices

únicos e 396 para os não únicos.

Reporta a existência de campos Date com Initial <

01/01/1800 caso tal opção esteja selecionada.

Verifica a possibilidade de estouro de registro maior que

8k(menos formatos >= x(8000).

Migração/Homologação Dicionário

Quando da migração, o protomss cria automaticamente

dois campos adicionais nas tabelas(progress_recid e

progress_recid_indent) com o objetivo de manter

compatibilidade com as funções RECID e ROWID.

Campos array(extent) serão convertidos com a convenção

campo##1 até campo##n onde n é o número de extents do

campo.

Para cada seqüência será criada uma tabela no SQL com

seus respectivos valores e uma stored procedure para emular

o comportamento do Progress.

Migração/Homologação Dicionário

Todos os campos a partir de x(8000) serão transformados

em campos text no SQL. Os menores que este formato serão

sempre varchar. Os campos tipo RAW também serão

convertidos para text.

Migração/Homologação Dicionário

Alteração Templates/Comportamento Programas

Desabilitação do botão de última ocorrência tanto para

Client-Server como para WEB.

Alteração das includes de dbtype para MSS

Validação para programas de tela dos valores para Campos

Date(> 01/01/1800) Client-Server e WEB

Unknown Values (?)

São suportados pelo Dataserver

Unknown Values e Brancos não são a mesma coisa

Os Unknown Values são armazenados como Nulls (?) e strings

vazias são armazenadas como 1 (um) espaço “ ” em

database SQL Server

Unknown Values (?)

Cláusulas do tipo >= ? e <= ? devem ser substituídas por > ? or = ? e

< ? or = ? para campos do tipo date, character, integer e decimal.

Cláusulas do tipo > ? devem ser substituídas por <> ? para campos

do tipo date.

Quando usamos unknown values em uma cláusula WHERE, apenas

se pode satisfazer a condição com operadores = (equal) ou <> (not

equal).

Unknown Values (?) - Exemplos

FOR EACH Customer NO-LOCK

WHERE Address <> "":

...

END.

PROGRESS

FOR EACH Customer NO-LOCK

WHERE Address <> "":

...

END.

SQL SERVER

Cust-Num Name Address

1 Lift Line Skiing 276 North Street

2 Urpon Frisbee

3 Hoops Croquet Co. ?

4 Go Fishing Ltd ?

5 Match Point Tennis

Cust-Num

1

3

4

Cust-Num

1

FOR EACH Customer NO-LOCK

WHERE Address <> "" OR

Address = ?:

...

END.

Cust-Num Name Address

1 Lift Line Skiing 276 North Street

2 Urpon Frisbee

3 Hoops Croquet Co. ?

4 Go Fishing Ltd ?

5 Match Point Tennis

FOR EACH Customer NO-LOCK

WHERE Address <> ?:

...

END.

PROGRESS

Cust-Num

1

2

5

FOR EACH Customer NO-LOCK

WHERE Address <> ?:

...

END.

SQL SERVER

Unknown Values (?) - Exemplos

Cust-Num Name Address

1 Lift Line Skiing 276 North Street

2 Urpon Frisbee

3 Hoops Croquet Co. ?

4 Go Fishing Ltd ?

5 Match Point Tennis

FOR EACH Customer NO-LOCK

WHERE Address >= ?:

...

END.

PROGRESS

Cust-Num

3

4

FOR EACH Customer NO-LOCK

WHERE Address >= ?:

...

END.

SQL SERVER

Não encontra

os registros

FOR EACH Customer NO-LOCK

WHERE Address > ? OR

Address = ?:

...

END.

Unknown Values (?) - Exemplos

FOR EACH customer

WHERE customer.address = "“:

DISPLAY customer.cust-num.

END.

PROGRESS e SQL SERVER

FOR EACH customer

WHERE customer.address = “ “:

DISPLAY customer.cust-num.

END.

Cust-Num Name Address

1 Lift Line Skiing 276 North Street

2 Urpon Frisbee

3 Hoops Croquet Co. ?

4 Go Fishing Ltd ?

5 Match Point Tennis 20 Bicep Bridge Rd

Cust-Num

2

Strings Vazias (“”) - Exemplos

Cust-Num Name Address

1 Lift Line Skiing 276 North Street

2 Urpon Frisbee

3 Hoops Croquet Co. ?

4 Go Fishing Ltd ?

5 Match Point Tennis 20 Bicep Bridge Rd

FOR EACH customer

WHERE customer.address BEGINS "“:

DISPLAY customer.cust-num address.

END.

PROGRESS e SQL SERVER

Cust-Num Address

1 276 North Street

2

5 20 Bicep Bridge Rd

FOR EACH customer

WHERE customer.address BEGINS “ “:

DISPLAY customer.cust-num address.

END.

Cust-Num Address

1 276 North Street

Embora “” e “ ” tenham o mesmo comportamento em cláusulas WHERE,

possuem diferentes resultados quando usados junto com a função BEGINS

Strings Vazias (“”) - Exemplos

Campos do tipo character possuem tamanho fixo

CREATE Customer.

ASSIGN Cust-Num = 1

Name = "Lift " + FILL("*", 50).

PROGRESS

CREATE Customer.

ASSIGN Cust-Num = 1

Name = "Lift " + FILL("*", 50).

SQL SERVER

CREATE Customer.

ASSIGN Cust-Num = 1

Name = SUBSTRING("Lift " +

FILL("*", 50), 1, 20).

Tamanho Fixo campos Caracter

Rowid

Fornece um único registro identificador que é compatível

com Progress e SQL Server

A Progress recomenda que sejam trocados os RECID por

ROWID nas aplicações existentes, mas a compatibilidade

com RECID funciona sem problemas.

Field Lists

Deve ser incluída a opção NO-LOCK em comandos OPEN

QUERY e FOR EACH que utilizam field lists

Comandos/Funções 4GL

Find

Suporta os comandos FIND FIRST, CURRENT, LAST, PREV e

NEXT

Compile

Se for alterado o nome do schema holder após o programa

ter sido compilado, deve ser recompilado contra o schema

holder renomeado

Não há necessidade de conectar o banco SQL Server para

compilar o programa. O schema holder contém todas as

informações que o compilador exige

Comandos/Funções 4GL

Begins/Matches

Evitar utilizar pois resulta em baixa performance

Se possível, utilizar claúsulas normais(=,>,<,<>)

Word-Index

Não é suportado pelo Dataserver

Contains

Está relacionado a word-index. Não é suportado pelo

Dataserver

Count-Of

Não é suportado pelo Dataserver

Raw-transfer

Converter o campo raw para caracter

Comandos 4GL não suportados

Current-Value

Pode ser utilizado a partir da 9.1C sem problemas.

Open Query

Registro criados após a abertura da query não estão

disponíveis, deve-se reabrí-la

Session:Time-Source

Deve retornar o local do schema holder

Fields

Somente pode ser utilizado com No-Lock

Where

Quando utilizado com campos text do SQL

Comandos 4GL não suportados

SetUserID

Poderá ser utilizado apontando para o Schema Holder.

Comandos 4GL não suportados

Existe perda de performance ao utilizar a função MATCHES

Contains

FOR EACH Customer WHERE Name CONTAINS "Bug":

DISPLAY Cust-Num Name.

END.

PROGRESS

Cust-Num Name

29 Bug in a Rug-by

FOR EACH Customer WHERE Name CONTAINS "Bug":

DISPLAY Cust-Num Name.

END.

SQL SERVER

FOR EACH Customer WHERE Name MATCHES "Bug*":

DISPLAY Cust-Num Name.

END.

Comandos 4GL - Exemplos

Session:Time-Source

SESSION:TIME-SOURCE = ldbname('sports').

DISP SESSION:TIME-SOURCE.

PROGRESS

c:\tmp\sports

SESSION:TIME-SOURCE = ldbname('sports').

DISP SESSION:TIME-SOURCE.

SQL SERVER

SESSION:TIME-SOURCE = ldbname(‘shsports').

DISP SESSION:TIME-SOURCE.

Comandos 4GL - Exemplos

A criação do registro tem tratamento diferente para Progress x SQL

Server

Pode-se forçar a gravação do registro através dos comandos:

Validate e Release (porém disparam a execução das Triggers de

Write do Dicionário)

Funções Rowid/Recid forçam a criação do registro, gravando os

campos mandatory (estas funções não disparam a execução das

Triggers de Write)

Criação/Escopo Registro

DO TRANSACTION:

CREATE customer.

name = “Smith”.

cust-Num = 10.

address = “1 Main St”.

END.

PROGRESS

Progress não cria o registro no CREATE. É

criado quando a informação do índice é

fornecida.

DO TRANSACTION:

CREATE customer.

name = “Smith”.

cust-Num = 10.

address = “1 Main St”.

END.

SQL SERVER

O registro é criado após executar o END.

Criação/Escopo Registro - Exemplos

DEFINE BUFFER bfCust FOR customer.

CREATE customer.

ASSIGN cust-num = 111.

FIND bfCust WHERE bfCust.cust-Num = 111.

DISPLAY bfCust.cust-num.

PROGRESS

DEFINE BUFFER bfCust FOR customer.

CREATE customer.

ASSIGN cust-num = 111.

FIND bfCust WHERE bfCust.cust-num = 111.

DISPLAY bfCust.cust-num.

SQL SERVER

Cust-Num

111

DEFINE BUFFER bfCust FOR customer.

CREATE customer.

ASSIGN cust-num = 111.

VALIDATE customer. /* ou RELEASE */

FIND bfCust WHERE bfCust.cust-num = 111.

DISPLAY bfCust.cust-num.

Criação/Escopo Registro - Exemplos

Se for setado valor default quando estiver criando o registro,

deve ser alterado antes de ser criado o outro (se o campo fizer

parte do índice único), pois senão irá causar um erro de

duplicidade de chave

Atualizações de registros são tratadas de forma similar a

criação dos registros. A atualização é feita no final do escopo ou

no final da transação

Criação/Escopo Registro

Share-Lock

Não utilizar

O dataserver ignora a opção share-lock, será necessário

verificar o código e optar por NO-LOCK ou EXCLUSIVE-LOCK

Exclusive-Lock e No-Lock

O comportamento destes é o mesmo do DB Progress

Deve-se utilizar optimistic lock

DO TRANSACTION:

FIND Customer WHERE Cust-Num = 11 NO-LOCK.

DISPLAY Name Credit-Limit Balance Sales-Rep.

PROMPT-FOR Name Credit-Limit Balance Sales-Rep.

FIND CURRENT Customer EXCLUSIVE-LOCK.

ASSIGN Name Credit-Limit Balance Sales-Rep.

END.

Lock de Registro

rep-blk:

repeat:

prompt-for customer.cust-num.

find customer using cust-num no-error.

if available customer then

update customer.cust-num name customer.state.

do-blk:

do on error undo do-blk, retry do-blk:

find state where state.state = customer.state.

display state.

set state.

end.

end.

Tratamento de Erros

PROGRESS SQL SERVER

Tratamento de Erros

Os comandos FOR EACH e FIND podem retornar os registros em

uma ordem imprevisível

Quando a ordem dos registros é importante deve-se utilizar as

opções By ou Use-Index, porém podem reduzir a performance

Ordem dos Registros

Query Tuning

A estrutura de uma query determina se o acesso a base de

dados está sendo feito de forma eficiente. O padrão para elevar a

performance é usar um critério de seleção para refinar o acesso ao

dado, mas podemos favorecer a execução de uma query através de

expressão específica Progress QUERY-TUNING.

Exemplos

FOR EACH <tabela> QUERY-TUNING <query-tuning-option)

OPEN QUERY <query> QUERY-TUNING <query-tuning-option)

Aumento de Performance

Opções QUERY-TUNING

array-message / no-array-message

cache-size

debug extended / debug sql / no-debug

join-by-sqldb / no-join-by-sqldb

lookahead / no-lookahead

separate-conection / no-separate-conection

Aumento de Performance

Joins

Para determinar se uma join é possível, o dataserver avalia se

os seguintes critérios são verdadeiros:

Todas as tabelas na join serem do mesmo banco lógico, isto é,

estarem contidas no mesmo schema

Cada tabela ter um único registro identificador

A query não incluir a opção USING

A query não incluir expressões que contenham BY ou campos

array

A join não exceder 10 níveis

Aumento de Performance

Queries que processam grande volume de registros, executam

melhor se usarmos no-lock, um grande tamanho de cache e field

list pequeno

Utilizar comandos FOR EACH, GET e OPEN QUERY de preferência,

ao invés do comando FIND, quando a performance estiver mais

lenta

Utilizar FOR FIRST ao invés de FIND FIRST. Utilizar FIND LAST ao

invés de GET LAST(Full Table Scan)

Aumento de Performance – Dicas Gerais

Utilizar field lists

Utilizar as opções de QUERY-TUNING

Utilizar sempre NO-LOCK quando possível

Não solicitar uma ordenação especial dos registros com cláusulas

que utilizam USE-INDEX ou BY, a menos que a aplicação exigir.

Permitir ao dataserver determinar o índice mais eficiente para

processar a query

Aumento de Performance – Dicas Gerais

Se for utilizar a cláusula BY para classificar uma grande

quantidade de registros, garanta a existência de um índice

correspondente para fazer uma classificação eficiente

Quando testar a existência de um registro, utilizar a função CAN-

FIND FIRST

Evite usar a função RECID. Ao invés disto, use a função ROWID

Aumento de Performance – Dicas Gerais

Problema

Only binary SQL fields can be updated with RAW data.(6187)

Campos com “-” após campo raw são criados com “_” no

schema

Causa

Existência campos do tipo raw no dicionário

Ação

Mudar o tipo de dado para CHAR

Problemas Conversão p/ SQL Server

Problema

O servidor de banco de dados especificado não suporta esta

função.(4634)

Causa

assign session:time-source = ldbname(‘mguni’).

Ação

O SQL não suporta a função time-source. Portanto, substituir o

nome do banco mguni pelo nome do schema holder shems2uni.

Problemas Execução com SQL Server

Problema

Database mguni has type MSS (869)

But connection to type Progress was requested.

Causa

&if "{&mguni_dbtype}" = "progress" &then

<executa instruções para progress>

&else

<executa instruções para outros tipos de bancos>

Ação

Alterar include i_dbtype.i para

&GLOBAL-DEFINE <nome-logico-banco>_dbtype MSS

Problemas Execução com SQL Server

Problema

Voce tentou comparar ou atualizar um campo caracter com um

valor maior do que o tamanho maximo. (6182)

Causa

def var v_cod_modul_dtsul_fim as character format "x(3)"

initial "zzzzzzzz" label "Modulo Final" column-label "Módulo“.

open query qr_sea_modul_dtsul FOR each modul_dtsul no-lock

where modul_dtsul.cod_modul_dtsul >= v_cod_modul_dtsul_ini

and modul_dtsul.cod_modul_dtsul <= v_cod_modul_dtsul_fim

by modul_dtsul.cod_modul_dtsul.

Pois o cod_modul_dtsul tem tamanho x(3) e está comparando com

a variável que apesar de ter o mesmo formato do campo, tem

valor inicial “zzzzzzzz” – x(8).

Ação

Identificado como bug, está corrigido no Patch 9.1D05. Para

gravação continua a mensagem, como ocorre no Oracle

Problemas Execução com SQL Server

Problema

GPF no momento de executar um OPEN QUERY ou FOR EACH com

mais de três níveis quando utilizada a função ROWID

Causa

def var rvar as rowid no-undo.

for each customer, each order of customer , each order-line of

order where rowid(order-line) <> rvar:

disp order.

end.

Ação

Bug no DataServer Progress. Liberado patch de correção 9.1D03

Problemas Execução com SQL Server

Problema

Registro Mostrado no For Each após criado em uma transação gerada

dentro deste Bloco, sendo que em Progress, todos os registros no

For Each já são trazidos para o Buffer, não apresentando o

problema, e em SQL Server, como cada iteração deste comando

gera um SELECT a ser executado no DataSource, estes registros são

trazidos, apresentando diferenças no resultado de alguns

programas.

Causa

A não existência de Transação no For Each, para que o programa

gere uma sub-transação desta transação maior no momento da

criação do Registro.

Ação

Utilização da claúsula TRANSACTION no For Each ou criação desta

através do comando DO.

Problemas Execução com SQL Server

Problema

Action Segment has exceeded its limit of 63488 bytes, in at line #

1611. (3307). A partir da versão 9.1C tem-se também a mensagem

9430, alertando para a utilização de mais de um action code no

programa, o que o impossibilita de ser rodado em versões

anteriores.

Causa

Excesso de procedures internas, código de programa. A partir da

9.1C, existem quatro segmentos de action code para o main Block.

O que minimiza o problema, mas ainda ocorrem problemas que

serão necessários retrabalhos. Quando ocorre o estouro de mais de

um action code, o Progress avisa mas compila o programa. Estes

somente poderão ser rodados contra a versão >= 9.1C.

Ação

Mover código para novos programas

Problemas Compilação com SQL Server

Problema

System error: Data/Time format error(6175)

Causa

Tentativa de gravar uma data inferior ao limite mínimo do SQL

Server de 01/01/1753. Este problema ocorria também na

comparação de datas inferiores a este valor, mas a Progress

implementou o parâmetro -Dsrv ZPRGRS_MSS_DATE_RANGE,1, que

realiza o tratamento da comparação de datas automaticamente

pelo DataServer.

Ação

Realizar a validação para que estas Datas não sejam gravadas com

valores menores que 01/01/1753.

Problemas Compilação com SQL Server

Comentários Finais

Estas limitações em relação ao SQL Server estão descritas na

técnica de programação “TECDES.04-Programação.doc”

As informações em relação aos pontos para migração de

dicionário estão em TEC.075 - Check List Inspeção Oracle-

SQL Server.doc

ORACLE

Campos Recid

Atributos não mandatórios fazendo parte do índice

Tabelas com número de atributos maior que 1000

Campos char com initial maior que o formato definido