Chapitre III SQL
(avec mes remerciements à l'INRETS auteur de ce document)
  • III-1 Introduction à SQL *
    • III-1-1 Requêtes de gestion de transaction *
    • III-1-2 Principes de SQL *
    • III-1-3 Les différents help sous SQL *
    • III-1-4 Noms des objets *
      • III-1-4-1 Conventions sur les noms des objets *
      • III-1-4-2 Identificateurs délimités *
    • III-1-5 Création de schéma *
    • III-1-6 Synonymes *
      • III-1-6-1 création d'un synonyme *
      • III-1-6-2 destruction d'un synonyme *
    • III-1-7 Types de données *
    • III-1-8 Les constantes utilisées dans SQL *
    • III-1-9 Principaux ordres SQL *
      • III-1-9-1 ordres SQL de manipulation de données *
      • III-1-9-2 ordres SQL d'administration de base *
  • III-2 Select, premiers pas *
    • III-2-1 L'ordre select *
    • III-2-2 Opérateurs de comparaison *
    • III-2-3 Opérateurs logiques *
    • III-2-4 Enlever les doubles *
    • III-2-5 Faire des recherches triées *
    • III-2-6 Mettre un commentaire dans une requête *
    • III-2-7 Recherches sur chaînes de caractères *
      • III-2-7-1 comparaison d'une colonne textuelle à une constante *
      • III-2-7-2 comparaison d'une colonne textuelle à un modèle, uniquement avec le comparateur like *
      • III-2-7-3 séquences spéciales *
  • III-3 Fonctions *
    • III-3-1 Fonctions de conversion de type *
    • III-3-2 Fonctions sur les dates *
    • III-3-3 Fonctions numériques *
    • III-3-4 Fonctions sur chaînes de caractères *
    • III-3-5 La fonction ifnull *
  • III-4 Conditions de recherche du where *
    • III-4-1 Définition d'une expression *
    • III-4-2 Définition d'une condition de recherche *
    • III-4-3 Utilisation de "between" *
    • III-4-4 Utilisation d'une "subquery" avec "in" : *
    • III-4-5 Utilisation d'une "subquery" avec "exists" *
    • III-4-6 Utilisation de "any et all" *
    • III-4-7 Utilisation de "is null" *
  • III-5 Jointure de tables *
    • III-5-1 Jointure interne *
    • III-5-2 Jointures externes *
  • III-6 Agrégations *
    • III-6-1 Les fonctions d'agrégation *
    • III-6-2 Agrégats avec clauses where, group by et having *
    • III-6-3 Ordre conceptuel dans lequel les opérations sont effectuées *
  • III-7 Définitions à propos de select, subselect, et subquery *
  • III-8 Création de table *
    • III-8-1 Syntaxe de l'ordre create table *
    • III-8-2 Valeurs nulles et par défaut des colonnes *
    • III-8-3 Contraintes sur les colonnes *
    • III-8-4 Contraintes sur les tables *
    • III-8-5 Clause with du create table *
    • III-8-6 Limitations *
  • III-9 Création de table à partir d'une recherche *
    • III-9-1 Syntaxe de create table *
    • III-9-2 Options supplémentaires de la clause with *
  • III-10 Création de tables temporaires *
  • III-11 Création de vue *
  • III-12 Destruction d'une table ou d'une vue *
  • III-13 Mise à jour de table *
    • III-13-1 Ajout de lignes dans une table *
    • III-13-2 Destruction de lignes d'une table *
    • III-13-3 Mise à jour de lignes d'une table *
  • III-14 Commentaires sur les tables et les colonnes *
  • III-15 Chargement et déchargement de tables (export/import) *
  • III-16 Sécurité des données*
    • III-16-1 Privilèges dans l'environnement OpenIngres *
    • III-16-2 Privilèges objets *
      • III-16-2-1 l'ordre grant *
      • III-16-2-2 suppression de privilèges *
      • III-16-2-3 privilèges dépendants *
      • III-16-2-4 vues et privilèges *
      • III-16-2-5 procédures de bases de données et privilèges *
      • III-16-2-6 privilège de mise à jour multicolonne *
    • III-16-3 Privilèges utilisateurs *
      • III-16-3-1 présentation *
      • III-16-3-2 opérations et syntaxe *
      • III-16-3-3 gestion des locations *
    • III-16-4 Contrôle d'accès par les vues *
    • III-16-5 Privilèges sur une base et sur l'installation *
      • III-16-5-1 généralités *
      • III-16-5-2 privilèges sur une base et l'installation complète *
      • III-16-5-3 exemples *
  • III-17 Les contraintes d'intégrité *
    • III-17-1 Créer une contrainte d'intégrité *
    • III-17-2 Lister les contraintes d'intégrité *
    • III-17-3 Détruire les intégrités en indiquant leurs numéros *
  • III-18 Gestions d'événements, règles et procédures *
    • III-18-1 Introduction *
    • III-18-2 Gestion des procédures *
    • III-18-3 Gestion des règles *
    • III-18-4 Exemples de règles et procédures *
  • III-19 Autres types de données : les objets spatiaux *
    • III-19-1 Le type point "point" *
    • III-19-2 Le type boîte "box" *
    • III-19-3 Le type segment "lseg" *
    • III-19-4 Le type ligne "line" *
    • III-19-5 Le type ligne longue "long line" *
    • III-19-6 Le type polygone "polygon" *
    • III-19-7 Le type polygone long "long polygon" *
    • III-19-8 Le type cercle "circle" *
    • III-19-9 Tableau des formats des types spatiaux *
    • III-19-10 Les opérateurs spatiaux disponibles *
    • III-19-11 Les fonctions disponibles sur les attributs de types spatiaux *

III-1 Introduction à SQL  
III-1-1 Requêtes de gestion de transaction 
Chaque entrée dans sql (isql) débute une transaction;

chaque sortie de sql (isql) termine une transaction.

Mises à jour et insertions ne sont sauvegardées qu'en fin de transaction, même si les données paraissent modifiées en cours de transaction. 
 
roolback; commit; valide les modifications apportées depuis le début de transaction, démarre une nouvelle transaction
set autocommit on | off; placé à on, chaque requête de modification dans la base est automatiquement validée. Sur les machines du CIR, par défaut à on lorsqu'on appelle isql ou sql, à off si on appelle ingmenu

III-1-2 Principes de SQL
SQL est un langage, normalisé par l?ANSI, permettant tant la définition que la manipulation et le contrôle d?une base de données relationnelle. Il sert à l?administrateur de la base (pour la gérer) comme à l?utilisateur final (pour l?interroger).

C?est un langage interactif (outil isql) ; il est également utilisé comme langage intégré ("embedded ") dans un langage de programmation (Fortran ou C) pour le développement d?applications.

Ce langage possède ses objets, sa syntaxe, ses commandes, ses mots-clés.

La commande help fournit des informations sur les objets de la base de données.

III-1-3 Les différents help sous SQL
help; donne le nom des objets accessibles de la base, leur propriétaire et leur type (table ou vue)
help * ; mêmes informations que help, plus noms et types des colonnes
help nom_objet; propriétaire, colonnes de l?objet (table, vue, index) nom_objet
help table nom_table; informations complètes sur l'organisation, la place occupée, le nombre de lignes, les colonnes et leur type
help index n_index; informations complètes sur l'index n_index 
help view vue; définition de la vue indiquée
help comment table nom_table; donne le commentaire attaché à la table nom_table
help comment column nom_table nom_col; donne le commentaire attaché à la colonne nom_col de la table nom_table
help permit on | integrity nom_table; informations sur les droits associés à la table ou la vue, les contraintes d?intégrité
help constraint nom_table affiche les contraintes définies sur les colonnes de la table nom_table. Ces contraintes ne sont pas les mêmes que les intégrités affichées par help integrity
help default nom_table affiche les valeurs par défaut définies sur les colonnes de la table
help procedure proc; informations sur la procédure proc
help rule nom_regle; informations sur la règle nom_regle
help synonym nom_syn information sur le synonyme nom_syn.
help synonym *. Pour afficher tous vos synonymes
help synonym *.* Pour afficher tous les synonymes qui vous sont accessibles
help help imprime cette liste : les 'objets' SQL (tables, vues, etc.) pour lesquels il y a un help
help sql ; donne la liste des commandes SQL pour lesquelles il existe un Help
help sql req_sql; informations sur l'ordre req_sqlen question 
III-1-4 Noms des objets
 
III-1-4-1 Conventions sur les noms des objets
Les règles pour nommer les objets d'une base (tables, colonnes, vues, procédures) sont les suivantes :
  • les noms ne peuvent contenir que des caractères alphanumériques et doivent commencer par une lettre ou (sauf les noms de bases) par un "blanc souligné";
  • il n'y a pas de distinction minuscules/majuscules, par défaut (voir le réglage de db_name_case);
  • les noms peuvent contenir les caractères suivants : chiffres de 0 à 9, #, @ et $; les noms utilisés comme identificateurs, entre guillemets peuvent contenir d'autres caractères spéciaux;
  • les noms de tables ne peuvent pas commencer par "ii" (réservé aux tables systèmes);
  • la longueur maximale d'un nom est de 32 caractères (24 dans l'ancienne version de Ingres)
Les noms des objets peuvent être donnés en utilisant des identificateurs "réguliers" (sans guillemets) ou "délimités" (entourés par des guillemets). III-1-4-2 Identificateurs délimités : Ils permettent l'utilisation de mots-clés dans les noms d'objets. Ils permettent l'utilisation de caractères spéciaux dans les noms :

blanc, étoile (*), tiret (-), etc., 

  • les noms doivent être entre guillemets 
  • les noms peuvent être utilisés pour les noms de : tables, vues, identificateurs de privilèges, database events, etc. 
Exemple de nom de table donné par un identificateur régulier : select * from employees Exemple de nom de table donné par un identificateur délimité : select * from "ma table" Vous ne pouvez pas introduire les caractères suivants dans des noms d'objets, en utilisant les identificateurs délimités ou réguliers :
 
\ ^
{ } DEL (ASCII 127 ou X'7F')
! ' (ASCII 96 or X'60')
~  

Pour utiliser des guillemets dans un identificateur délimité, il faut les répéter, par exemple : """nom""identificateur""" est interprété comme :

"nom"identificateur"

Les blancs de fin sont supprimés des noms utilisant les identificateurs délimités. Par exemple, la requête :

create table "essai blancs " (scolumn int);

crée une table appelée "essai blancs";

si la chaîne ne contient que des blancs, le nom consistera en un seul blanc.

III-1-5 Création de schéma
Un schéma, qui correspond logiquement à une base à l'intérieur d'une base, regroupe les différents objets (tables, vues, privilèges) qui appartiennent à un utilisateur.

Le nom du schéma est celui de l'utilisateur qui l'a créé. Chaque utilisateur ne peut créer qu'un seul schéma par base. Il n'y aura donc pas création de schéma s'il en existe déjà un pour l'utilisateur.

La création d'un schéma se fait soit par une instruction spécifique, soit, si un utilisateur n'a pas de schéma, automatiquement lors de la création de la première table par l'utilisateur

Syntaxe : .

create schema authorization nom_schéma [creation_objet {creation_objet}]; creation_objet peut être un create table, create view ou grant.

Exemple :

create schema authorization mon_nom_user

create table foyer85 

(ident integer, an i1, depcom integer, cprof i1, nbvoi i1)
III-1-6 Synonymes

III-1-6-1 création d'un synonyme

On peut créer des synonymes (qui sont des alias) pour les tables, les vues ou les index. create synonym nom_syn for [schema.]nom_objet; Ces synonymes peuvent être employés à la place des noms réels (ceux indiqués dans une instruction create) dans tout ordre SQL : le remplacement par les noms d'objet réels se fait au moment de l'exécution.

Exemple

create synonym "table foyer" on foyer
Nom Propriétaire Type
foyer mon_nom_user table
"table foyer"  mon_nom_user synonym
III-1-6-2 destruction d'un synonyme

drop synonym nom_syn 

Exemple drop synonym "table foyer"


III-1-7 Types de données

liste des types possibles
 
Classe Catégorie Type de données Usage et valeurs limites
Caractères longueur fixe c  
    char (character) char(i) 0<i<2001
  Varying length text  
    varchar varchar(i) 0<i<2001
    long varchar long varchar(i) 0<i<2goctets
Numérique numérique exact integer (integer4)  entier sur 4 octets, de -2,1*10**9 à +2,1*10**9
    smallint (integer2)  entier sur 2 octets, de -32768 à 32767
    integer1 entier sur un octet, de -127 à 128
    decimal decimal (p, s)

p : précision (nombre total de chiffres), 1 <=p<= 31

s : scale, échelle, nombre de chiffres après la virgule 

  numérique approché float (n) float (n)

où n = précision 

0 <=n<= 52

0< n <=7 équivaut à real, float4 stockage sur 4 octets

8<= n <=52 équivaut à float, float8, double precision 

stockage sur 8 octets

    float (float8, double precision)  flottant sur 8 octets, 10**38 max. (17 déc.)
    float4 (real) flottant sur 4 octets, 10**38 max. (7 déc.)
Abstrait   date donne date ou date+heure, 12 octets stockés, 25 à l'affichage
    money monnaie, avec un F à gauche, 8 octets
  clé logique table_key table_key [not | with system_maintained]

la valeur de la colonne est une clé logique unique dans la table, et peut être automatiquement maintenue par Ingres (with system_maintained)

    object_key  object_key [not | with system_maintained]

la valeur de la colonne est une clé logique unique dans la base, et peut être automatiquement maintenue par Ingres (with system_maintained)

Binaire   byte byte (n) données binaires de longueur fixe

n<= 2000

    byte varying byte varying (n) données binaires de longueur variable
    long byte long byte (n) données binaires 

n<= 2 gigaoctets

III-1-8 Les constantes utilisées dans SQL
Vous pouvez utiliser les constantes suivantes dans les requêtes SQL :
 
Constante Signification
now date et heures courantes. Cette constante doit être donnée entre apostrophes.
null Indique une valeur manquante ou inconnue dans une table.
today date du jour. Cette constante doit être donnée entre apostrophes.
>user identificateur de l'usager de la session Ingres (pas l'usager Unix)
current_user comme user. 
system_user identificateur de l'usager Unix qui a démarré la session Ingres
initial_user identificateur de l'usager Ingres au début de la session
session_user comme user.

Ces constantes peuvent être utilisées dans les requêtes et expressions, par exemple :

select date('now');

insert into commandes 

(numero, agent, date_facture)

values ('123', user, date('today')+date('7 days'));

Pour préciser l'usager effectif au début de la session, utilisez le flag -unom des commandes (isql, sql, ...) ou la clause "identified by" de l'instruction "sql connect". III-1-9 Principaux ordres SQL  
III-1-9-1 ordres SQL de manipulation de données 
select toutes recherches 
update  mise à jour (corrections)
insert  ajout de lignes 
delete destruction de lignes 
III-1-9-2 ordres SQL d'administration de base 
create schema création de schéma
copy table  chargement/déchargement. de tabledans un fichier 
create table création de table
alter table modification de contraintes sur une table
create view  création de vue logique
modify change l'organisation physique des données, pour accélérer les recherches 
create index  création d'un index
grant autorisation d'accès aux données d'un objet (table, vue, procédure)
create integrity définit des contraintes d'intégrité sur une table
drop détruit un objet (table, vue, accès, index)
create synonym création de synonymes


 

III-2 Select, premiers pas

 
III-2-1 L'ordre select
Le résultat d'un select est équivalent à une table.

Syntaxe : 

select col1 {,coli} from tab1 {,tabi} [ where cond1 {opl condi}]; 

où : coli est un nom de colonne, tabi un nom de table, condi une condition de recherche;

exemple : select tranche from commune where depcom = 93063 ;

select ident, nbpers from foyer 

where cprof = 44 and cnaiss >= 45 ;

select * from vehicule where kman > 20000 ;


III-2-2 Opérateurs de comparaison
 

> < 

>= <= 

= != ou <> 

like 

Les opérateurs de comparaison peuvent être utilisés avec des colonnes de type numérique ou caractère, à l?exception de like qui ne s'utilise qu'avec des colonnes de type caractère.

Conditions des comparaisons avec un type decimal :
 

type1 type2  
decimal decimal pas de conversion
decimal float decimal converti en float
decimal integer integer converti en decimal
III-2-3 Opérateurs logiques 
  not and or
Attention à leurs priorités quand ils sont combinés : il faut mettre des parenthèses.  III-2-4 Enlever les doubles

select distinct

exemple : select distinct tranche from commune;


III-2-5 Faire des recherches triées
 

select distinct dept from commune order by dept [asc|desc];
  • le tri peut s'effectuer sur plusieurs colonnes 
  • les colonnes triées doivent être présentes dans la clause select 
  • le tri est ascendant par défaut (asc)
récapitulatif de la syntaxe du select étudié jusqu'ici 

select [distinct] expr [ as libelle] {, expr [ as libelle]} 

from table

[where condition_recherche {or | and [not] condition_recherche}];

III-2-6 Mettre un commentaire dans une requête 

exemple : /* ...commentaire...*

select * from commune 

where dept = 77 

/* and psdc > 500 */ and tranche = 3 g


III-2-7 Recherches sur chaînes de caractères 

III-2-7-1 comparaison d'une colonne textuelle à une constante 

expression compar constante 

compar étant : < > = <= >= !=

la constante s'écrit entre cotes ex : nom = 'Dupont' 

III-2-7-2 comparaison d'une colonne textuelle à un modèle, uniquement avec le comparateur like

nom_col [not] like modèle

Dans un modèle, on peut utiliser des caractères spéciaux :

% n'importe quelle chaîne de caractères, y compris la chaîne vide 

_ n'importe quel caractère 

ex : '%ton' reconnaîtra 'Tonton', 'mironton', 'ton' 

ex : '___ton' reconnaîtra 'Tonton', 'chaton' 

III-2-7-3 séquences spéciales \[aB3\] reconnaîtra un caractère parmi a, B ou 3 

\[1-x\] reconnaîtra un caractère pris entre 1 et x dans l'ordre des caractères ASCII (de 1 à x dans notre cas) 

Attention : pour ces séquences spéciales entourées de crochets, il faut obligatoirement indiquer quel est le caractère d'échappement. Dans l?exemple qui suit c?est le contre-slash. Sinon, SQL comparerait à la chaîne ?\[A-D\]?.

ex : 

nom like '\[A-D\]%' escape \ (tous les noms commençant par A,B,C,D)

Les fonctions s'appliquent aux constantes, colonnes, expressions; elles peuvent s'imbriquer en respectant le type de leurs arguments.


III-3 Fonctions

III-3-1 Fonctions de conversion de type
char (qque) type quelconque en char 
varchar (qque) type quelconque en varchar 
date (ch) toute chaîne en date 
float4 (^dat) tout sauf date en float4 ; idem float8
int1 (^dat) tout sauf date en integer1 ; idem int2 et int4
decimal ( expression 

[,précision [,scale] ] )

tronque la partie décimale si besoin; peut générer une erreur de débordement si le nombre est trop grand.

Valeurs de p et s pour les conversions par la fonction decimal, selon le type converti :
 

type converti
p
s
money
15
2
float
15
0
integer4
11
0
smallint/integer1
5
0
III-3-2 Fonctions sur les dates 
d1 + | - id2 ajouter/retrancher un intervalle de date à une date 
dow (date)  jour de semaine de date en anglais ('Mon', 'Tue') 
date_trunc (unité, date)  date tronquée à l?unité indiquée 
date_part (unité, date) entier, valeur de l'unité indiquée
interval (unité, interv) convertit un intervalle de date en valeur décimale de l'unité indiquée 

Les unités mentionnées ci-dessus doivent être obligatoirement indiquées entre cotes.

exemple :

select distinct date_part(?year?, datachat) from vehicule ; donne les différentes valeurs de l?année d?achat du véhicule liste des unités et synonymes admis :
second seconds sec secs  
minute minutes min mins  
hour hours hr hrs  
day days      
week weeks wk wks  
month months mo mos  
quarter quarters qtr qtrs  (trimestre)
year   years yr yrs
constantes connues de Ingres :  'now'

'today'

exemples de dates : 

'02/28/85' 

'28-feb-85', 

'02/28/85 10:30:25' 

'02/28/85' + '1 yr 2 mo 3 day' 

Pour pouvoir utiliser les dates, en indiquant jour, mois, an ainsi : 'jj/mm/aa', il faut positionner, au niveau Unix, la variable II_DATE_FORMAT par la commande :  $ setenv II_DATE_FORMAT MULTINATIONAL ;

III-3-3 Fonctions numériques

Opérations sur les colonnes et constantes numériques : 

** * / + - 

pas de restriction théorique à leur combinaison;

attention aux priorités, mettre des parenthèses 

fonctions abs (x)

atan (x)

cos (x)

exp (x)

log (x)

mod (i, j) i, j et le résultat de mod sont des entiers

sin (x)

sqrt (x) 

remarques sur le type "decimal" :

Les opérateurs et fonctions arithmétiques peuvent être utilisés avec des types "decimal" :

  • les opérations arithmétiques peuvent se faire sur des valeurs de précision et échelle différentes; 
  • les fonctions ensemblistes (max, min, avg, sum) prennent des arguments de type decimal
  • la fonction avg rend un résultat plus précis qu'avec des types float
  • la fonction mod tronque les arguments à leur partie entière et rend un entier; 
  • toutes les autres fonctions numériques convertissent les valeurs en float et retournent un float.
III-3-4 Fonctions sur chaînes de caractères 
charextract (c1,n) le n-ième caractère de c1 
concat (c1,c2)  concaténation 
c1 + c2  concaténation 
left (c1,l1)  les l1 premiers caractères de c1
right (c1,l1)  les l1 derniers caractères de c1
size (c1)  taille déclarée de c1 
length (c1)  longueur de la chaîne sans les blancs à droite 
locate (c1,c2)  1ère occurrence de c2 dans c1 
lowercase (c1)  c1 en minuscules 
uppercase (c1)  c1 en majuscules 
pad (c1)  c1 et ses blancs de fin 
trim (c1)  c1 sans blancs de fin 
squeeze (c1)  compresse les caractères d?espacement
shift (c1,ndep)  déplacement vers la droite ou la gauche

Remarque :

Le type de donnée n?est pas changé par ces fonctions : ainsi, si adresse est un char(150), la fonction left (adresse,3) rendra un char(150).

III-3-5 La fonction ifnull elle permet d'attribuer une valeur à une colonne prenant la valeur null

ifnull (v1, v2) a pour valeur v1 si v1 est non "null" et pour valeur v2 si v1 est "null" 

Par exemple, les fonctions d'agrégations sum, avg, max et min rendent une valeur nulle si l'ensemble sur lequel elles portent est vide. Pour recevoir une valeur non nulle, vous pouvez utiliser la fonction ifnull comme ceci :

ifnull(sum(employee.salaire)/25, -1)

Si la somme de employee.salaire est nulle, on aura -1.
 


III-4 Conditions de recherche du where III-4-1 Définition d'une expression Qu'est-ce qu'une expression ? c'est une combinaison d'opérateurs et d'opérandes qui donnent une valeur ou un ensemble de valeurs : constante 

colonne 

expression oper_arith expression 

fonction(expression) 

exemples :  date_part ('year', datachat) = 1900 + ancstr

left (char (depcom), 2)

III-4-2 Définition d'une condition de recherche

Une condition de recherche est une collection de prédicats, éventuellement combinés par les opérateurs booléens or,and, not , avec éventuellement un parenthésage pour indiquer l?ordre d?évaluation. III-4-3 Utilisation de "between"

exp between exp1 and exp2 

exemple: sélection des véhicules dont le rapport masse/puissance fiscale est compris entre 2 et 8 select * from vehicule where masse / puisfisc between 2 and 8 ;


III-4-4 Utilisation d'une "subquery" avec "in" :

exp in (exp1, exp2, ... , expi); 

ou  exp in ( select...)  exemple : sélection des véhicules dont la puissance fiscale est une valeur de la liste 2, 7, 11 select * from vehicule where puisfisc in (2, 7, 11); exemple : sélection des identificateurs de foyers qui habitent des communes de plus de 10000 habitants select distinct ident from foyer where depcom in

(select depcom from commune

where psdc > 10000);


III-4-5 Utilisation d'une "subquery" avec "exists"

le prédicat est vrai si la subquery retourne un ensemble de valeurs non vide : [not] exists (select... exemple : sélection des identificateurs de foyers qui ne possèdent pas de véhicule select ident from foyer

where not exists

(select * from vehicule

where vehicule.ident = foyer.ident) ;


III-4-6 Utilisation de "any et all"

exp comparateurs any | all (select...)

any est équivalent à in ( select ...)

exemple : sélection des foyers qui ont un revenu supérieur à tous les revenus des csp "44" select * from foyer

where revenu > all

(select revenu from foyer

where cprof = 44 ) ;

exemple : sélection des identificateurs de foyers qui ont au moins un véhicule dans la base select ident from foyer

where ident = any

(select ident from vehicule ) ;


III-4-7 Utilisation de "is null"

exp is [not] null

exemple : sélection des identificateurs de foyers qui n'ont pas de variable depcom définie select ident from foyer where depcom is null ;
III-5 Jointure de tables  
III-5-1 Jointure interne
On peut joindre jusqu'à 30 tables.

La définition de la jointure apparaîtra dans la clause where du select.

Exemple : donner l'identificateur, l'année de naissance, l'année du panel, et la puissance fiscale de tous les véhicules de tous les foyers : 

select f.ident, f.cnaiss, f.an, v.puisfisc

from foyer f, vehicule v 

where f.ident = v.ident and f.an = v.an ;

On utilise des synonymes abrégés pour désigner les tables s?il risque d?y avoir une ambiguïté du fait de l?existence de la même colonne dans plusieurs tables.

Toutes les tables intervenantes doivent être présentes dans le from.

On doit spécifier, à l'aide des synonymes, la tabled'appartenance pour toute colonne commune à deux tables.

La jointure interne donne comme table résultats une table contenant les lignes communes aux 2 tables d'origine.

Par exemple, si on fait la jointure entre une table de foyers et une table de véhicules, suivant la condition "tel foyer possède un véhicule", la jointure interne ne donnera que les foyers ayant un ou plusieurs véhicules dans la table véhicules.

Exemple de schéma conceptuel :
 

table foyer
 
table vehicule
tables de départ
ident
 
 
 
 

A1

 
ident
 
 
 
 

A2

tous les "ident" A2 de la table véhicule sont contenus dans la partie A1 de la table foyer; les "ident" B1 de la table foyer ne sont pas contenus dans la table véhicule
       
B1
 
B2
 
       
       

 
 
 
 
table foyer
 
table vehicule
jointure interne
ident
 
 
 
 

A1+

 
ident
 
 
 
 

A2

A1+ représente les tuples de A1 de mêmes ident que A2,

éventuellement dupliqués pour avoir le même nombre de lignes dans A1+ et dans A2
 
 


 
 

exemple : sélection des identificateurs, département, nombre de personnes des foyers ainsi que l'année d'enquête et la marque-modèle des véhicules associés

select f.ident, f.depcom, f.nbpers, v.an, v.marqmod

from vehicule v inner join foyer f

on f.ident = v.ident

équivalent à  select f.ident, f.depcom, f.nbpers, v.an, v.marqmod

from vehicule v , foyer f

where f.ident = v.ident


III-5-2 Jointures externes

On peut désirer aussi avoir les informations pour les adultes sans enfants, ou les enfants sans parents, voire les deux cas réunis : on voudra donc des informations sur des lignes ne vérifiant pas la condition de jointure et on parlera alors de jointure externe, qui peut être "à gauche", "à droite", ou "complète".

Dans tous les cas, une table (ou vue) résultant d'une jointure sera dite interne si seules les lignes vérifiant la condition de jointure sont produites, et externe si toutes les lignes sont produites, qu'elles vérifient ou pas la condition de jointure. Les colonnes provenant de la table interne ne vérifiant pas la condition de jointure auront la valeur "null".

Syntaxe de la jointure externe :

select [all |distinct] * | expression [as colonne_resultat]

{, expression [as colonne_resultat] }

from source

{ type_jointure join source on condition_jointure }

[ where .......... ]

où type_jointure peut être : inner | left | right | full

L'option inner join désigne la jointure interne, les autres les 3 types de jointures externes.

Dans chaque cas de jointure externe, on désigne la table (ou vue) qui sera externe, c'est-à-dire dont toutes les lignes seront affichées; ainsi, en cas de left join, c'est la table de gauche qui est externe; en cas de right join, c'est celle de droite, et les deux en cas de full join.

Les jointures peuvent être emboîtées dans une clause from. Elles sont alors évaluées de gauche à droite. On peut, en utilisant des parenthèses, forcer l'ordre d'évaluation.

Schémas des jointures externes correspondant aux tables foyer et véhicule précédentes:

table foyer
 
table vehicule
 
ident
 
 
 
 

A1+

 
ident
 
 
 
 

A2

jointure externe

complète : A full join B on A.ident = B.ident
 
 
 
 
 
 


 
 

NULL

 
 
 

B2


 
 
 
 

 


 
 

B1

 
 
 

NULL


 
 

 

exemple : sélection d'informations sur tous les foyers et tous les véhicules

select f.ident, f.depcom, f.nbpers, v.an, v.marqmod

from foyer f full join vehicule v 

on f.ident = v.ident

table foyer
 
table vehicule
 
ident
 
 
 
 

A1+

 
ident
 
 
 
 

A2

jointure externe 

gauche : A left join B on A.ident=B.ident

A est la table externe
 
 
 
 

B1

 

 
NULL

 
 

 

exemple : sélection de tous les foyers et des informations sur leurs véhicules éventuels

select f.ident, f.depcom, f.nbpers, v.an, v.marqmod

from foyer f left join vehicule v 

on f.ident = v.ident

table foyer
 
table vehicule
 
ident
 
 
 
 

A1+

 
ident
 
 
 
 

A2

jointure externe  droite A right join B on A.ident=B.ident

B est la table externe 
 
 
 
 
 
 


 
 

NULL

 
 
 

B2


 
 
 
 

 

exemple : sélection de tous les véhicules et des informations sur les foyers éventuels associés

select f.ident, f.depcom, f.nbpers, v.an, v.marqmod

from foyer f right join vehicule v on f.ident = v.ident;


III-6 Agrégations III-6-1 Les fonctions d'agrégation Elles opèrent sur une colonne de valeurs.

A l'intérieur de sql, elles sont référencées comme des Set Functions

Ce sont : 

avg sum count max min  elles ne peuvent pas être imbriquées;

elles ne peuvent pas être dans une clause where

elles ne peuvent être que dans les clauses select et having;

avg, count, sum peuvent avoir l'argument distinct;

les valeurs nulles sont ignorées, sauf pour count(*) qui compte les lignes.

exemple : sélection de la moyenne du nombre de véhicules par foyer :

- sans clause where

select avg(nbvoi) as moyenne from foyer; - avec clause where select avg (nbvoi) as moy_1a2 from foyer 

where nbvoi <= 2;

le where élimine les lignes avec 3 véhicules ou plus avant calcul de la moyenne.  III-6-2 Agrégats avec clauses where, group by et having Trouver le nombre moyen de véhicules par CSP ; on ne s'intéresse qu'aux foyers ayant au plus 2 véhicules : select cprof, avg(nbvoi) 

from foyer 

where nbvoi <=

group by cprof ;

En premier le where élimine.

Les lignes restantes sont groupées avant calcul de la moyenne.

Le regroupement peut se faire suivant plusieurs colonnes.

Le select ne peut contenir que des agrégats, ou des constantes et les colonnes du group by

exemple : même question que précédemment, mais en ne s'intéressant qu'aux CSP avec plus de 2 foyers dans la base :

select cprof, avg(nbvoi) as moy 

from foyer 

where nbvoi <=

group by cprof 

having count(ident) > 2;

Les groupes ne satisfaisant pas la clause having sont éliminés.

La clause having doit produire une seule valeur par groupe

III-6-3 Ordre conceptuel dans lequel les opérations sont effectuées Dans le cas de la requête précédente :
  1. formation du produit cartésien des tables indiquées dans le from 
  2. élimination des lignes ne satisfaisant pas le where 
  3. regroupement des lignes suivant la clause group by 
  4. élimination des groupes ne satisfaisant pas la clause having 
  5. évaluation des expressions dans la clause select 
  6. si select distinct, élimination des lignes en double dans la table résultat 

III-7 Définitions à propos de select, subselect, et subquery

Tout ce qui commence par select est un "subselect" .

Un subquery n'apparaît que dans une condition de recherche, il est introduit par, et seulement par :

any | all, 

in | not in, 

[not] exists 

un ordre select est l'union de subselect(s) : select ident from foy84 

union

select ident from foy86 where ident i

( select ident from vehicule 

where ancstr >= 2);
Cet ordre select contient 3 subselect et 1 subquery .

Il y a toujours deux façons d'écrire une même requête mettant en oeuvre plus d'une table :

- avec jointure

- avec subquery


III-8 Création de table

 
III-8-1 Syntaxe de l'ordre create table
On ne crée que la structure de la table, sans données. create table [schema.]nom_tab (

(colonne_spec {, colonne_spec })

[, [constraint nom_contrainte] contrainte_table 

{, [constraint nom_contrainte] contrainte_table}

[with with_clause])

colonne_spec peut être :  nom_colonne type

[[with] default default_spec | with default | not default]

[with null | not null]

[[constraint nom_contrainte] contrainte_colonne 

{, [constraint nom_contrainte] contrainte_colonne}]

où type fait partie des types vus au paragraphe III-1-4;

avec le type "logical key", on peut ajouter la clause "with system maintained"

III-8-2 Valeurs nulles et par défaut des colonnes not default spécifie que la valeur de la colonne doit être définie;

with default spécifie que si aucune valeur n'est fournie, on aura 0 pour les types numériques et money, une chaîne vide pour les types caractères et date;

[with default] default_spec spécifie la valeur que prend la colonne par défaut si elle n'est pas fournie;

exemple :

create table dept(dnom char(10),

location char(10) default 'PARIS',

creation date default '01/01/97',

budget money default 10000);

with null spécifie que la colonne accepte les valeurs nulles;

not null spécifie que la colonne ne peut pas prendre la valeur "null";

Lorsque l'on autorise la valeur logique 'null' pour une colonne, un octet est rajouté pour le stockage de cette colonne dans chaque ligne de la table.

exemple : 

create table foyer 

(ident integer not null not default,

an integer2

depcom integer

nbpers integer1

cnaiss integer1

cprof integer1

nbvoi integer1

revenu integer1

ponder float4

);

Combinaison de la clause with | not null avec la clause with | not default :
 
with null La colonne accepte les valeurs nulles. Si aucune valeur n'est fournie, Ingres insère "null".
with null with default La colonne accepte les valeurs nulles. Si aucune valeur n'est fournie, Ingres insère un 0 ou chaîne vide selon le type.
with null not default La colonne accepte les valeurs nulles. L'utilisateur doit fournir une valeur
not null with default La colonne n'accepte pas les valeurs nulles. Si aucune valeur n'est fournie, Ingres insère un 0 ou chaîne vide selon le type
not null not default ou not null La colonne est obligatoirement renseignée et n'accepte pas les valeurs nulles, cas des colonnes de type "primary key", par exemple.

Avec "with system maintained", la seule clause de défaut valide est "with default". Elle est prise par défaut si vous l'oubliez. La seule clause de nullité valide est "not null". Si vous ne spécifiez pas de contrainte de colonne ou de clause de nullité, la clause "not null" est prise par défaut.

III-8-3 Contraintes sur les colonnes contrainte_colonne permet de définir les contraintes de colonnes suivantes :
  • unique spécifie que l'on ne peut pas avoir deux lignes avec la même valeur de colonne;
  • check (controle_spec) définit une condition que doit vérifier la colonne
exemple create table emps (nom char(25), sal money

constraint cont_sal check (sal > 0));

la contrainte définit la condition salaire positif;
  • references [schema.]nom_tab[(nom_col)] définit une contrainte référentielle entre la colonne et une colonne d'une autre table;
exemple :  create table emp (enom char(10), edept char(10) references dept(dnom)); la contrainte référentielle définie ici assure qu'un employé ne peut avoir un département non présent dans la table "dept";
  • primary key spécifie que la colonne est une clé primaire (une seule possible par table) et qu'une contrainte référentielle dans une autre table pourra y faire référence;
exemple :

table référencée :

create table partenaires (partno intprimary key...); table qui la référence : create table liste (ipartno int...

foreign key (ipartno) references (partenaires));

dans la table "liste", ipartno est une clé externe, liée par contrainte référentielle à la table "partenaire", c'est-à-dire, automatiquement, à la clé primaire qui a été définie dans cette table; III-8-4 Contraintes sur les tables Une contrainte au niveau de table peut être : 
  • unique(nom_col {, nom_col) permet de spécifier que les données d'un groupe de colonnes sont uniques;
exemple : create table depts(dnom char(10) not null,

dlocation char(10) not null)

constraint unique_dept unique (dname, dlocation));

La contrainte de nom "unique-dept" assure que 2 départements de même localisation ne peuvent avoir le même nom. Les colonnes sont obligatoirement déclarées "not null";
  • check (controle_spec) permet de spécifier une condition à vérifier pour un groupe de colonnes;
exemple : create table dept ( dnom char(10),

location char(10),

budget money,

depenses money,

constraint cont_montant check (budget > and

depenses <= budget));

Cette contrainte assure que chaque département a un budget et que les dépenses n'excèdent pas le budget.
  • references [schema.]nom_tab[(nom_col {, nom_col})] permet de spécifier des contraintes référentielles au niveau de la table, en utilisant l'option "foreign key"
exemple : create table chef (nom char(10),

empno char(5),

...

foreign key (nom, empno) references emp);

Cette contrainte vérifie le contenu des colonnes "nom" et "empno" par rapport aux colonnes correspondantes de la table "emp" pour assurer que quiconque entré dans la table "chef" est un employé de la table "emp". Puisque le nom de la colonne référencée est omis, la table "emp" doit avoir une contrainte de "primary key" qui définit les colonnes nom et empno. III-8-5 Clause with du create table Les options possibles sont :
  • location = (disc-logic-i {, disc-logic-i }) spécifie les localisations de la table; ceci permet de répartir les données sur différents disques, si l'administrateur Ingres l'a prévu;
  • [no]journaling spécifie avec ou sans journalisation de la table
cette option ne prend effet qu'après lancement, au niveau Unix de la commande ckpdb. Il n'y a pas de journalisation par défaut;
  • [no]duplicates permet ou pas les lignes doubles
cette option ne prend effet qu'après modification de la structure physique par la requête modify, doubles autorisés par défaut;
  • label_granularity = table | row | system_default spécifie le niveau du label de sécurité;
  • security_audit = (audit_opt {, audit_opt}) spécifie un niveau d'audit par ligne (audit_opt=row) ou par table (audit_opt=table);
  • security_audit_key = (nom_col) cette option permet de spécifier un attribut qui sera écrit dans le fichier log de l'audit; par exemple on utilise le numéro d'employé comme clé d'audit
create table employe (nom char(60), emp_no integer)

with security_audit = (table, row),

security_audit_key = (emp_no);

III-8-6 Limitations
nom de table <= 32 caractères 

nom de colonne <= 32 caractères 

au plus 300 colonnes par table

au plus 2008 octets par ligne, sauf pour les colonnes de type "blob" (binary long object), long varchar et long byte, qui peuvent aller jusqu'à 2 gigaoctets.


III-9 Création de table à partir d'une recherche

  Le résultat d'une recherche est une table; on peut l'affecter à une table, temporaire ou permanente et les types des colonnes de la nouvelle table correspondent au type calculé dans le select, ce qui peut permettre des conversions de type dans certains cas. Il est également possible de renommer les colonnes de la nouvelle table; il n'est par contre pas possible de leur assigner un type.

III-9-1 Syntaxe de create table

create table nom_table [(nom_col1, nom_col2,..)] 

as select ...

[with with_clause];

exemple : on crée la table des "sur-motorisés" avec les foyers ayant au moins 3 véhicules create table sur_mot

as select * from foyer where nbvoy >= 3 ;

La table sur_mot est créée et chargée avec les lignes sélectionnées, le nom des colonnes reste inchangé. III-9-2 Options supplémentaires de la clause with
  • structure = hash | heap | isam | btree spécifie la structure de stockage de la table (voir le chapitre optimisations) 
  • key = (nom_col {, nom_col}) spécifie les colonnes servant de clés 
  • fillfactor = n spécifie le pourcentage de remplissage des pages de données primaires (voir modify
  • minpages = n spécifie le nombre minimum de pages primaires pour une table en "hash"(voir modify
  • maxpages = n spécifie le nombre maximum de pages primaires pour une table en "hash"(voir modify
  • leaffill = n spécifie le pourcentage de remplissage des pages d'index "feuilles" en BTREE (voir modify
  • nonleaffill = n spécifie le pourcentage de remplissage des pages d'index "non feuilles" en BTREE (voir modify
  • compression[= ([[no]key] [,[no]data])] | nocompression spécifie si la clé ou les données sont compressées 
  • allocation =n spécifie le nombre de pages initialement allouées à la table (4 par défaut) 
  • extend =n spécifie le nombre de pages pour l'extension de la table (16 par défaut)


III-10 Création de tables temporaires
  OpenIngres permet la création de tables temporaires, qui :

- existent pour la durée de la session, 

- sont automatiquement détruites à la fin de la session.

Le nom de la session fait partie du nom de la table, ce qui élimine les conflits de noms.

L'accès à ces tables est rapide, car elles sont, autant que possible, conservées en mémoire :

- pas de privilèges à vérifier, 

- pas d'entrées de catalogues à parcourir, 

- pas de logging ou de locking à gérer (ni sauvegarde, ni verrouillage).

Restrictions

- elles ne sont visibles que de la session qui les a créées, 

- elles disparaissent à la fin de la session, 

- on ne peut leur appliquer que les instructions modify et drop.

Syntaxe :

création d'une table temporaire originelle

declare global temporary table session.table_name

(nom_col format {, nom_col format})

on commit preserve rows

with norecovery

[with_clause]

création d'une table temporaire à partir d'une autre table, avec un "subselect" declare global temporary table session.table_name

(nom_col {, nom_col}) 

as subselect

on commit preserve rows

with norecovery

[with with_clause]

Options possibles de with_clause :

location = (nom_loc {, nom_loc})

[no]duplicates

allocation = n

extend =n

Pour les tables temporaires créées avec un subselect, les options suivantes peuvent être utilisées dans with_clause:

structure = hash | heap | isam | btree

key = (liste_col)

fillfactor = n

minpages = n

maxpages = n

leaffill = n

nonleaffill = n

compression[ = ([[no]key] [,[no]data])] | nocompression

Vous pouvez donner à une table temporaire le même nom qu'une table permanente. Par exemple, pour l'utilisateur "jules", une table permanente matable sera nommée par le système "jules.matable" et la table temporaire de nom "matable" sera nommée par le système "session.matable".

III-11 Création de vue
  Une vue est une définition logique, sans stockage de données. Cela permet des calculs (et/ou jointures) sur des données qui sont refaits à chaque appel, prenant en compte toutes les modifications intervenues dans les données. Seule la définition est stockée (accessible par help view nom_vue).

create view nom_vue [(nom_col1, nom_col2,..)]

as select ...;

[with check option]

exemple : créer la vue des foyers "sur-motorisés" create view sur_mot

as select * from foyer where nbvoy >= 3 ;

La clause facultative with check option permet de définir,, lors de la mise à jour de données via la vue, que la (les) conditions de la clause where doit être vérifiée. Si elle n'est pas présente, aucune vérification ne sera faite.

Avec cette clause, on peut insérer des lignes, mettre à jour des colonnes, par l'intermédiaire d'une vue, si les conditions du where sont respectées

exemple : créer la vue des foyers de Paris

create view foyerparis as 

select ident, depcom, an 

from foyer85

where depcom/1000 = 75 with check option;

L'insertion suivante échouera insert into foyerparis values (90168 , 93063, 84); L'insertion suivante réussira insert into foyerparis values (90168 , 75114, 84); Une vue s'utilise comme une table, mais les opérations qu'elle sous-tend sont effectuées à chaque appel.

exemple : recherche dans la vue "sur_mot" 

select * from sur_mot where dep = '87';

III-12 Destruction d'une table ou d'une vue
 

drop nom_table | nom_vue | nom_index{, nom_table | nom_vue | nom_index} ;ou 

drop table nom_table {,nom_table};

drop view nom_vue {,nom_vue} ;

drop index nom_index {,nom_index} ;

La destruction d'une table n'est possible que par son propriétaire ou l'administrateur, elle est effectuée sans demande de confirmation et détruit à la fois le contenu de la table(toutes les lignes) et le schéma de la table. Les droits, intégrités, règles et vues référençant une table seront également détruits sans avertissement. Voir les outils d'export de base pour sauvegarder les définitions sql d'une base (avant la destruction d'une table).

exemple : destruction de la table "commune" 

drop table commune ; Quand l'une des tables ayant servi à la définition d'une vue est détruite, la vue est également détruite.

III-13 Mise à jour de table

III-13-1 Ajout de lignes dans une table On peut ajouter à une table des lignes créées comme résultats d'une recherche insert into nom_table [(col1, coli)] select ... ; exemple : insertion de lignes dans "commune", depuis des lignes de la table "com_ext" insert into commune 

select depc, depc / 1000, 0, psdc, comclair 

from com_ext 

where depc / 1000 = 95 ;

Autre forme moins utilisée, car elle ne permet l'ajout que d'une seule ligne à la fois :  insert into nom_table [(col1, coli, )] values (exp1, expi ) exemple : insertion d'une ligne dans "commune"  insert into commune (depcom, dept, tranche, psdc, comclair) 

values (94060,94,2,849,'Queue-en-Brie');

Pour les deux formes, les colonnes non spécifiées prennent la valeur null, si celle-ci est permise. III-13-2 Destruction de lignes d'une table

delete from nom_table [where cond_rech] ;

exemple : destruction des lignes de "commune" correspondant à la tranche inférieure à 2 delete from commune where tranche <= 2 ; C'est une destruction "logique". III-13-3 Mise à jour de lignes d'une table

update nom_table [syn] [from nom_table1 [syn1] {,nom_table2 [syn]}] 

set coli = expi {, colj = expj

[ where cond_rech] ;

exemple : mise à jour de la variable psdc pour la commune ayant depcom = 94060 update commune 

set psdc = 9722 

where depcom = 94060;

exemple : mise à jour de la variable ponder des foyers en fonction de la variable tranche de leur commune update foyer f from commune c 

set ponder = ponder + float4(c.tranche) / 10.0 

where c.depcom = f.depcom ;
 


III-14 Commentaires sur les tables et les colonnesIls permettent une documentation interne à la base, et sont chargés/déchargés par unloaddb et copydb. La taille d'un commentaire est limitée à 1600 caractères.

Création : 

comment on table [schema.]nom_tab is 'comment'

comment on column [schema.]nom_col is 'comment'

exemples : comment on table foyer is 'décrit les ménages du panel SOFRES depuis l''année 1978'; 

comment on column depcom is 'nombre à 5 chiffres, les 2 plus à gauche représentent le département, le reste le numéro de commune';

Destruction : comment on table [schema.]nom_tab is ''

comment on column [schema.]nom_col is ''

Pour savoir ce que contient le commentaire : help comment table [schema.]nom_tab  {, [schema.]nom_tab} help comment column [schema.]nom_tab nom_col  {, nom_col} Les commentaires sont stockés dans le catalogue système iidbms_comments. C'est un premier pas vers la documentation d'une base (en dehors des outils développés par le CIR) mais la grande rigidité de cette requête sql ne facilite pas son utilisation.

III-15 Chargement et déchargement de tables (export/import)

  La commande copy table permet de charger une table à partir d'un fichier ou de la décharger dans un fichier. 

Le descripteur de format de lecture - écriture est très simple. 

Le format est indépendant du type de colonne. 

Syntaxe :

copy [table] nom_table 

(col = format [with null [(value)]]

{ ,col = format [with null [( value) ] ] } ) 

into | from 'chemin_fichier' 

[with option {,option} ]

Les formats de lecture :
 
char(0) lit tout type de colonne, jusqu'à la rencontre d'une virgule, tabulation ou retour chariot
c0 comme char(0), mais n'est plus documenté
char(N) 1<N<2000, lit tout type de colonne sur une longueur de N caractères
cN comme char(N), mais n'est plus documenté
dN saut de N caractères dans le fichier, à associer à une colonne bidon; 

Les formats peuvent s'écrire aussi en précisant un délimiteur de champ autre que la virgule (tabulation, retour chariot), il faut alors le préciser notamment après char(0) ou c0

ex : char(0)'?'

Certains caractères spéciaux sont représentés par un mot clé :

nl retour chariot 
tab caractère de tabulation 
sp espace 
comma virgule 
colon deux points 

Il faut absolument faire figurer, dans le format de lecture, le délimiteur de ligne au bon endroit (char(0)nl dans l'exemple qui suit). Ces formats peuvent être utilisés également en écriture pour exporter des données, mais il existe des outils Ingres et CIR pour le faire plus aisément.

exemple de contenu du fichier à importer : 

94033,94,2,51868,Fontenay-sous-Bois 

94075,94,2,7921,Villecresnes 
 
 

copy table commune (

depcom = char(0)

dept = char(0),

tranche = char(0)

psdc = char(0)

comclair = char(0)nl)

from ' /serveur/cir/dest/com.fich' ;

Autre exemple : les données sont formatées 94033 94 2 ??? 51868 Fontenay-sous-Bois

94075 94 2 +++ 7921 Villecresnes
 
 

copy table commune (

depcom = char(5)

dept = char(5),

tranche = char(2) with null('X'), 

xx = d4

psdc = char(7)

yy = d1,

comclair = char(20)nl

from 'com2.don'

with on_error = continue, log= 'fich_erreurs' ;

Les deux options du with sont intéressantes lorsque l'on n'est pas sûr des données, elles permettent de continuer la copie, même en cas d'erreur, et de stocker toutes les lignes erronées dans un fichier d'erreur, qui, corrigé, pourra lui-même servir de fichier de données.

La table suivante explicite les formats de données des fichiers par rapport aux types de données SQL.
 
Format Stockage (Copy Into) Lecture (Copy From)
byte(0) donnée binaire de longueur fixe (complétée de zéros si nécessaire).  donnée binaire de longueur variable terminée par la première virgule, tabulation ou fin de ligne rencontrée.
byte(0)delim donnée binaire de longueur fixe (complétée de zéros si nécessaire). Le délimiteur sur 1 caractère est inséré immédiatement après la valeur (zéro n'est pas un délimiteur autorisé). donnée binaire de longueur variable terminée par le caractère spécifié.
byte(n) où 1< n < 2000 donnée binaire de longueur fixe donnée binaire de longueur fixe
byte varying(0) donnée binaire de longueur variable précédée d'une longueur sur 5 car. donnée binaire de longueur variable précédée d'une longueur sur 5 car.
byte varying(n

où 1< n < 2000

donnée binaire de longueur fixe précédée d'une longueur sur 5 car. Complétée par des zéros si nécessaire donnée binaire de longueur fixe précédée d'une longueur sur 5 car.
char(0) Chaîne de longueur fixe, complétée par des blancs si nécessaire. Pour les données character, la longueur de la chaîne écrite dans le fichier est la même que la longueur de la colonne chaîne de longueur variable terminée par la première virgule, tabulation ou fin de ligne rencontrée.
char(0)delim Complété à la longueur déclarée de la colonne. Le délimiteur sur 1 caractère est inséré immédiatement après la valeur (un espace n'est pas un délimiteur autorisé). chaîne de longueur variable terminée par le caractère spécifié.
char(n) où 1< n < 2000 Chaîne de longueur fixe Chaîne de longueur fixe
d0 (non applicable) Champ bidon. Chaîne de longueur variable terminée par la première virgule, tabulation ou fin de ligne rencontrée. La donnée dans le champ est sautée

 
 
 
 
Format Stockage (Copy Into) Lecture (Copy From)
d0delim Indique une colonne bidon délimitée. Au lieu de mettre une valeur dans le fichier, copy insère le délimiteur spécifié. (Contrairement au format dn, ce format n'insère pas le nom de colonne.) champ bidon : lu comme une chaîne de longueur variable délimitée par le caractère spécifié. La donnée dans le champ est sautée.
date donnée de format date. Champ date.
decimal donnée de format decimal donnée de type decimal.
dn Indique une colonne bidon délimitée. Au lieu de mettre une valeur dans le fichier, copy insère le nom de la colonne n fois. Par exemple, si vous spécifiez x=d1, le nom de colonne 'x' est inséré une fois, si vous spécifiez x=d2, le nom de colonne 'x' est inséré deux fois, etc. Vous pouvez spécifier un délimiteur comme nom de colonne, par exemple, nl=d1. champ bidon : lu comme une chaîne de longueur variable de la longueur spécifiée. La donnée dans le champ est sautée.
float flottant double précision flottant double précision
float4 flottant simple précision flottant simple précision
integer entier sur 4 octets entier sur 4 octets
integer1 entier sur 1 octet entier sur 1 octet
long byte(0) Donnée binaire stockée dans des segments. Chaque segment est composé d'un entier, donnant la longueur du segment, suivi par un espace, puis par le nombre de bytes spécifié. Si la colonne peut avoir la valeur null, il faut spécifier la clause "with null". Une colonne vide est stockée comme un 0 suivi par un espace. Champ de type long byte.

 
 
 
 
Format Stockage (Copy Into) Lecture (Copy From)
long varchar(0) Donnée stockée dans des segments. Chaque segment est composé d'un entier, donnant la longueur du segment, suivi par un espace, puis par le nombre de caractères spécifié. Exemple de 2 segments : le premier segment a 5 caractères et le second a 10 caractères :

5 abcde

10 abcdefghij...

Si la colonne peut avoir la valeur null, il faut spécifier la clause "with null". Une colonne vide est stockée comme un 0 suivi par un espace.

Champ de type long varchar
money donnée de format. money champ de format. money
smallint entier sur 2 octets entier sur 2 octets
varchar(0) chaîne de longueur variable précédée de 5-characteres donnant la longueur  chaîne de longueur variable précédée de 5-characteres donnant la longueur 
varchar(n

où 1<n< 2000

chaîne de longueur fixe précédée de 5-characteres donnant la longueur. Complétée si nécessaire par des caractères null chaîne de longueur fixe précédée de 5-characteres donnant la longueur.


III-16 Sécurité des données
 

III-16-1 Privilèges dans l'environnement OpenIngres Les privilèges définissent les opérations qu'un usager peut exécuter. Ils sont mis en oeuvre via l'usage de permissions. Les permissions autorisent ou interdisent à un usager l'exécution d'opérations.

On distingue :

  • des privilèges utilisateurs que l'usager peut exécuter dans l'installation OpenIngres. 
  • des privilèges sur les objets d'une base. 
  • des privilèges de base et d'installation, décrivant les opérations que l'usager peut exécuter ou non, et pouvant être définis pour les bases individuelles ou pour toutes les bases de l'installation OpenIngres.
On peut maintenant avoir les pouvoirs de l'administrateur d'une base sans être soi-même administrateur, et donner des privilèges d'accès aux objets privés n'appartenant pas à l'administrateur, ainsi que transmettre des privilèges.

Les contrôles d'accès par les vues sont étendus à d'autres fonctionnalités, permettant de gérer les accès sur les colonnes.

Enfin les privilèges sur les bases et l'installation OpenIngres permettent une gestion plus précise des privilèges.

III-16-2 Privilèges objets Ils donnent les opérations qui peuvent être exécutées sur les objets d'une base de données.

Avec l'ancienne version de Ingres, les privilèges se rapportaient seulement aux objets que possédait l'administrateur de la base, les objets possédés par d'autres utilisateurs étaient toujours privés.

Avec OpenIngres tout utilisateur peut accorder des privilèges sur les objets qu'il possède, et ce à n'importe quel autre usager.

Les privilèges objets sont manipulés en utilisant les ordres SQL grant et revoke, qui sont les ordres de la norme ANSI pour la manipulation de privilèges.

create/drop/permit sont les ordres spécifiques à Ingres, et sont retirés progressivement

(revoke et drop permit se comportent différemment).

III-16-2-1 l'ordre grant L'option grant donne aux utilisateurs, groupes et rôles les privilèges sur les tables, vues, procédures, événements, bases et l'installation OpenIngres courante. grant all [privileges] | privilege {, privilege} 

|role {, role}

[excluding (nom_col {, nom_col})] 

[on [type_objet] [schema.]nom_objet}] 

to public | [type_autoris] id_autoris {, id_autoris} 

[with grant option]

privilege est un mot clé qui peut être :

select

update

delete

insert

execute (uniquement pour les procédures, droit unique des procédures)

references donne le droit à créer des contraintes référentielles sur les tables et colonnes spécifiées

copy_into

copy_from

all [privileges] tous les droits (doit être seul présent) 

type_objet peut être :

table

procedure

database

dbevent

current installation

Par défaut, le type d'objet est "table". Le privilège possible dépend du type d'objet

nom_objet est le nom de l'objet désigné 

type_autoris est le type d'autorisation à qui vous donnez les privileges :

user (par défaut)

group

rôle

id_autoris est le nom de users, groups, ou roles à qui vous donnez les privileges, ou public (droit accordé à tous). 

exemple : on met l'accès en lecture à tous sur la table "commune"

grant select on commune to public; exemple : on met l'accès en lecture et mis à jour à l'usager bl sur la table "commune" grant insert, update on commune to bl; Les usagers peuvent toujours donner les accès sur les tables et les événements des bases qu'ils possèdent.

Avec "with grant option", les usagers peuvent déléguer (en cascade) à d'autres usagers le droit de donner des accès aux objets, pour les mêmes privilèges qu'on leur a donnés (ceci s'applique donc aux objets possédés par d'autres usagers).

Exemple : passage de privilèges

Rémy : 

grant select, insert on remy.dept to line with grant option Line :  grant select on remy.dept to michel with grant option Michel :  grant select on remy.dept toalain Rémy, Michel, Line et Alain peuvent faire des sélections de la table remy.dept possédée par Rémy.

Rémy et Line peuvent insérer dans cette table.

Rémy, Michel et Line peuvent donner toutes les permissions aux autres usagers, Alain ne peut pas.

with grant option n'est pas valide pour les permissions données aux groupes et rôles, ni pour les permissions données sur les bases ou sur l'installation courante.

III-16-2-2 suppression de privilèges Dans la version OpenIngres, les privilèges sont supprimés en utilisant l'ordre SQL revoke, remplaçant l'ordre drop permit revoke [grant optionfor] all [privileges] | privilege {, privilege} 

[excluding (nom_col {, nom_col},)] 

on [type_objet [schema.]nom_objet {, [schema.]nom_objet} 

| current installation from public

| [type_autoris] id_autoris {, id_autoris} cascade | restrict

Attention, l'un des mots-clés cascade ou restrict doit forcément être présent, sauf si on supprime le privilège sur une base ou sur l'installation courante.

cascade enlève le privilège à supprimer, et aussi tous ceux qui en découlent.

restrict enlève le privilège spécifié seulement s'il n'y a pas d'autres privilèges dépendants : ceci évite d'avoir des privilèges "orphelins".

On ne peut supprimer que les privilèges qu'on a soi-même donnés.

On peut enlever le privilège "with grant option".

On peut ôter en cascade les privilèges dépendants.

Drop permit Peut toujours être utilisé pour enlever les privilèges.

Nécessite d'être le propriétaire de l'objet, mais pas nécessairement le donneur d'accès.

Echoue si un privilège ou objet quelconque est abandonné.

with grant option

III-16-2-3 privilèges dépendants Donner des permissions à d'autres usagers affecte les chaînes de permissions et les permissions dépendantes.

Ainsi, de l'exemple précédent :

Le privilège select de Michel sur remy.dept dépend de Line ayant à la fois les droits select et grant option

Si les droits select ou grant option de Line sont supprimés, la permission select de Michel l'est également. On peut donc faire :

revoke grant option for select on remy.dept 

from line cascade ;

ou : revoke select on remy.dept 

from line cascade ;


III-16-2-4 vues et privilèges


  La création de vues nécessite le privilège de sélectionner sur toutes les tables ou vues sur lesquelles la vue est basée.

Donner un droit sur une vue nécessite de pouvoir donner les permissions désirées sur toutes les tables ou vues de la base.

Le mieux est d'avoir le privilège grant option sur les autres tables ou vues.

La définition d'un privilège sur une vue est transmissible.

III-16-2-5 procédures de bases de données et privilèges Le propriétaire d'une procédure de base de données doit posséder les objets que celle-ci utilise ou avoir les privilèges sur les objets qu'elle nécessite.

Elles sont parfois appelées procédures de base de données "actives".

La procédure de base de données devient "dormante" si les conditions changent après la création de la procédure de base de données (suppression de privilèges, par exemple ...).

Le propriétaire doit posséder le privilège grant option sur tous les objets référencés dans la procédure de base de données pour y donner les privilèges à d'autres usagers (elles sont appelées procédures autorisables).

III-16-2-6 privilège de mise à jour multicolonne grant permet de restreindre la mise à jour aux colonnes :

soit la table : vendeur (vnom, vnum, rue, ville, dept, code) :

grant select on vendeur to public ; 

grant update (vnom, rue, ville, dept, code)

on vendeur to public ; 

la colonne vnum ne peut pas être modifiée.

Le privilège revoke update est utilisable pour les colonnes :

revoke update (vnom) on vendeur from public ; vnom ne peut plus être modifiée, les colonnes restantes sont toujours modifiables.

revoke excluding ne laisse qu'un privilège intact :

revoke update excluding (rue) on vendeur from public restrict ;  seule la colonne rue peut encore être modifiée. III-16-3 Privilèges utilisateurs

III-16-3-1 présentation

Il y a 6 principaux privilèges utilisateurs, qui concernent en fait seulement l'administration de base ou d'installation Ingres :

Security Administrator (Administrateur de la Sécurité)

Equivalent au SuperUser des versions Ingres précédentes, donne tous les droits. Create Database (création de base)

Habilitation à créer des bases. Set Trace Flags (mettre des traces)

Possibilité de faire des "trace flags" ou des "trace points". Operator (Opérateur)

Possibilité d'exécuter checkpoint (point de reprise) et rollforward (recharge de la base à partir de checkpoint) tout comme l'administrateur de la base. Maintain locations

Possibilité de gérer les locations pour l'installation. Audit all activity (journalisation de l'ensemble de l'activité)

Tous les accès d'enregistrements effectués par les usagers ayant ce droit seront écrits dans le fichier d'audit.

III-16-3-2 opérations et syntaxe On donne (grant) et retire (revoke) les privilèges via accessdb.

On peut aussi les manipuler via les nouvelles commandes SQL :

create/alter/drop user : créer, modifier, détruire un usager

ceci nécessite d'avoir le privilège "Security Administrator" et doit être effectué à partir d'une session connectée à la base maître iidbdb.

Syntaxe des privilèges utilisateurs :

create user nom_usager 

[with [group = id_groupe | nogroup]

[,privileges =(privilege{,privilege})|noprivileges]] ;
 
 

alter user nom_usager 

[with [group = id_groupe | nogroup

[,privileges =(privilege{,privilege})|noprivileges]] ;
 
 

drop user nom_usager;

III-16-3-3 gestion des locations

Ils concernent l'administration de l'installation OpenIngres.

Les usagers ayant le privilège "maintain locations" peuvent gérer les locations :

par accessdb.

ou par les nouveaux ordres SQL :

create location nom_location with area = nom_disque 

[, usage = (type_usage {, type_usage}) | nousage];
 
 

alter location nom_location with area = nom_disque 

[, usage = (type_usage {, type_usage}) | nousage];

alter location ne change pas l'usage pour une base utilisant déjà la location nommée.

alter location remplace le précédent usage d'une location et n'est pas cumulatif.

drop location nom_location ; on ne peut détruire une location utilisée par une autre base. III-16-4 Contrôle d'accès par les vues L'ordre SQL grant a des possibilités limitées pour le contrôle d'accès aux colonnes :

on peut préciser les colonnes qu'un usager peut modifier, mais on ne peut pas préciser les colonnes qu'un usager peut sélectionner.

Les vues fournissent une restriction horizontale et verticale de l'accès aux données usager

Le privilège select sur une vue n'implique pas le privilège select sur les tables sur lesquelles cette vue est basée.

Exemple : permettre à chaque usager de voir les noms et salaires des employés qu'il gère :

create view v_emp as select nom, salaire 

from emp where gest = dbmsinfo('user_name') ;

grant select on v_emp to public ;

Tous les usagers peuvent effectuer des sélections depuis la vue v_emp.

Chaque usager voit seulement les articles des employés qu'il gère, son nom étant alors dans la colonne 'gest'.

III-16-5 Privilèges sur une base et sur l'installation

III-16-5-1 généralités

Ces privilèges ne concernent pas l'utilisateur final, sauf s'il est aussi administrateur de base. Certains privilèges peuvent être donnés tantôt sur une base, tantôt sur l'installation OpenIngres entière.

Ils ne s'appliquent pas aux administrateurs de base sur leurs propres bases.

Ils ne s'appliquent pas aux administrateurs sécurité dans l'installation OpenIngres entière.

Les privilèges peuvent être actifs ou inactifs.

Le niveau base prévaut sur le niveau installation (on peut autoriser localement une permission au niveau base alors qu'elle est ôtée au niveau installation).

III-16-5-2 privilèges sur une base et l'installation complète Les privilèges sur une base sont gérés soit par l'administrateur de la base concernée, soit par l'administrateur système OpenIngres, soit par tout usager ayant le privilège "Security Administrator"

Les privilèges sur l'installation OpenIngres sont gérés soit par l'administrateur système OpenIngres, soit par tout usager ayant le privilège "Security Administrator"

Tout ceci doit être effectué dans une session "terminal monitor" connectée à la base iidbdb.
 
[no]access interdit/autorise l'accès usager
[no]create_table interdit/autorise la création de tables
[no]create_procedure interdit/autorise la création de procédures
[no]lockmode interdit/autorise le changement de l'état du verrouillage
[no]query_row_limit libère/limite le nombre de lignes qu'une requête peut fournir
[no]query_io_limit libère/limite le nombre d'entrées-sorties possibles pour une requête
[no]db_admin interdit/autorise la possibilité d'agir comme un DBA
[no]update_syscat interdit/autorise la possibilité de modifier les catalogues systèmes

On donne ou enlève ces privilèges en utilisant grant et revoke.

Pour donner les privilèges de base et d'installation :

grant base_priv {,base_priv} 

on database nom_base | current installation to

[role | user | group] identifier | public ;
pour ôter les privilèges de base et d'installation : revoke base_priv {,base_priv} 

on database nom_base | current installation

from [role | user | group] identifier | public ;

III-16-5-3 exemples

grant nocreate_table 

on current installation to public ;

grant nocreate_procedure 

on current installation to public ; 

grant create_table, create_procedure 

on database basetest to public ; 

grant query_row_limit 100 

on current installation to user remy ; 

revoke query_row_limit 

on current installation from user remy ; 



III-17 Les contraintes d'intégrité
  III-17-1 Créer une contrainte d'intégrité

create integrity on nom_tab is cond_recherche ;

Restrictions : la condition de recherche ne peut porter que sur la tablenom_tab, sans subselect, ni agrégat.

exemple : la variable dept de commune doit être comprise entre 00 et 98

create integrity on commune is dept between 00 and 98;


III-17-2 Lister les contraintes d'intégrité

help integrity nom_tab

Les contraintes d'intégrité sont numérotées.
  III-17-3 Détruire les intégrités en indiquant leurs numéros

drop integrity on nom_tab n1 {, n2} ;



III-18 Gestions d'événements, règles et procédures
  III-18-1 Introduction


  Ingres sait gérer en interne des déclenchements automatiques d'ensemble d'actions pré-programmées en langage sql (étendu) lorsque certains événements surviennent dans la base.

Une règle dira lors d'un événement dans la base de données, c'est à dire une insertion, une mise à jour ou une destruction, quel ensemble d'actions entreprendre ; cet ensemble d'actions est contenu dans des procédures, qui sont nommées et paramétrables.

On gère ces objets comme des tables, avec des ordres de création, de description, de destruction, et de gestion des droits (pour les procédures uniquement).

Ces règles permettent de créer des contraintes d'intégrité référentielles : par exemple, interdire la suppression d'un client de la table client s'il a encore des factures en cours dans la table facture.

Une autre utilisation permet, comme nous le verrons, de déclencher des mises à jour en cascade, ce qui peut permettre de retrouver une arborescence (comme la recherche de descendants dans un arbre généalogique).

III-18-2 Gestion des procédures L'ordre de création d'une procédure est le suivant : [create] procedure [schema.]nom_proc [(nom_param [=] type_param [with | not default] [with | not null]

{, nom_param [=] type_param} [with | not default][with | not null])]

=|as declare

[declare_section]

begin

ordre {; ordre}[;]

end

Description des paramètres :

nom_proc est le nom de la procedure;

nom_param est le nom d'un paramètre de la procédure; les paramètres peuvent être passés par valeur ou par référence;

type_param est le type du paramètre;

declare_section est une liste de variables locales à la procedure;

ordre : ordre SQL

Une procédure peut avoir zéro ou plusieurs paramètres d'entrée (nom_param), dont on doit préciser le type.

On doit indiquer ensuite après l'ordre declare, la liste des variables internes à la procédure, et leur type détaillé. 

Puis vient, à l'intérieur d'un bloc begin-end, la suite des ordres à effectuer. 

Certaines séquences de programmation sont possibles, en dehors des ordres sql usuels, comme les blocs if-then-else et les blocs while-endwhile

Deux ordres sql sont interdits seulement pour le déclenchement par des règles : commit, et rollback

On peut utiliser également des ordres de mise en erreur de l'événement déclencheur, avec message à l'utilisateur (voir exemples).

Appel d'une procédure en sql :

execute procedure [schema.]nom_proc  [(nom_param = val{, nom_param = val})]  On obtient la description d'une procédure par l'ordre  help procedure nom_proc {, nom_proc} ; Pour retrouver la liste et description de toutes les procédures, on remplace nom_proc par l'astérisque '*'.

L'ordre de destruction d'une procédure est le suivant :

drop procedure nom_proc ; La seule autorisation possible sur une procédure est "execute", et ne peut être donnée que par le propriétaire de la base sur ses procédures. Ceci permet d'affiner les droits d'accès, car ils sont indépendants des droits sur les tables (possibilités de mise à jour à travers une procédure, sans droit "update" sur une table).

Les procédures sont déclenchées par des règles ou à l'intérieur de programmes 

(C, fortran, ..) ou dans des applications Windows4gl.

III-18-3 Gestion des règles L'ordre de création d'une règle est le suivant : create rule nom_regle 

after maj_sql {, maj_sql} 

on | from | into nom_table [referencing [old as ref_ancien] [new as ref_nouv]]

[where cond_rech]

execute procedure nom_proc 

[[nom_param = val {, nom_param = val} ) ] ;
La règle nom_regle va activer l'exécution de la procédure nom_proc, sur certains ordres de mise à jour sql, "maj_sql", qui sont soit insert, delete ou update tentés sur n'importe quelle ligne (colonne pour l'update) de la table nom_table. La procédure référencée dans la règle doit exister au moment de création de cette dernière. Le mot clef referencing a peu d'intérêt, en revanche sa fonction, implicitement remplie par les mots clefs old et new est importante. La condition de recherche cond_rech peut vouloir comparer, lors d'une mise à jour, les valeurs anciennes et nouvelles d'une colonne ; pour les différencier, elles seront préfixées par old. et new.. III-18-4 Exemples de règles et procédures Voici une procédure qui permettra de vérifier, dans une base de gestion de personnel, s'il existe bien un corps, classe, et échelon dans la grille statutaire pour y positionner un agent. 

La procédure a trois paramètres d'entrée (corps, classe, echelon) et deux variables internes check_grille qui ne peut avoir que la valeur 1 ou 0 dans notre cas (existence unique ou absence du triplet corps-classe-echelon fourni) et une variable caractère qui contiendra le message d'erreur fourni à l'utilisateur, s'il a fourni des données erronées. 

On remarquera que les variables locales sont, uniquement à l'intérieur des ordres sql, précédées d'un ":" , afin de différencier colonnes de tables et variables locales.

create procedure position_valide (

corps char(5),

classe integer2

echelon char(2)

as 

declare check_grille integer;

mess varchar(100) not null;

begin 

select count(*) into :check_grille 

from grille 

where corps = :corps and

classe = :classe and

echelon = :echelon;

if check_grille = 0 then

mess = ' saisie sans correspondance avec la table grille ';

raise error 1 :mess;

return; 

endif;

end

Et voici maintenant la règle qui déclenchera la procédure, lorsque l'on voudra soit insérer un nouvel agent sur une position donnée, soit faire une mise à jour sur une nouvelle position. create rule verif_grille 

after insert, update from agent 

execute procedure postion_valide( 

corps = new.corps, 

classe = new.classe, 

echelon = new.echelon);

On passe à la procédure les valeurs nouvelles proposées soit à l'insertion, soit en mise à jour, ce qui explique le mot-clef new.

Voici maintenant un exemple de mise à jour en cascade. Il s'agit de plusieurs arbres généalogiques sur une population, décrit de la façon suivante dans une table :

pers(num, nom, est_enfant_de, rang)

La colonne est_enfant_de contient le numéro (num) du parent, rang est une colonne numérique non renseignée qui nous servira au classement.

Notre problème est de trouver au sein de la population, aussi facilement que possible, tous les descendants d'une personne donnée, avec leur rang de descendance. Ceci sera possible en une seule requête, mais pour le moins étonnante, car nous passerons par une mise à jour (update) du rang de la personne dont on cherche la descendance, pour obtenir automatiquement le classement souhaité.

Nous allons créer un ensemble procédure-règle, qui, lorsque l'on mettra à jour la colonne rang avec la valeur 1 pour un individu donné, rangera ses descendants en augmentant rang de 1 à chaque génération (2 pour les enfants, 3 pour les petits-enfants,..), rang devenant null (manquant) pour tous les autres individus (ascendants ou autres familles). Une seule mise à jour (rang = 1 pour un numéro donné) va déclencher une cascade de mises à jour sur la table pers.

create procedure maj_pers_rang(

num integer1, bid integer1) as

begin

/* version faisant une mise a null pour chaque demande

si maj volontaire de rang à 1 */

if (:bid = 1) then

update pers

set rang = null

where num != :num;

endif;

update pers

set rang = :bid + 1

where est_enfant_de = :num;

end ;

create rule cherche_descendance

after update (rang) of pers

where new.rang is not null

execute procedure maj_pers_rang(

num = new.num , bid = new.rang);

Voici les résultats de deux mises à jour et consultation de la table pers :

/* recherche de la descendance du numéro 7 */ 

1> update pers set rang = 1 where num = 7

(1 row)

2> select * from pers

3> where rang is not null order by 4
 
num nom est_enfant_de rang
7 Muriel 3 1
14 François 7 2
15 Maurice 7 2
16 Gerard 15 3
18 Georgette 16 4
19 Germaine 16 4
20 Loic 16 4

(7 rows)

/* recherche de la descendance du numéro 15 */ 

2> update pers set rang = 1 where num = 15

(1 row)

2> select * from pers

3> where rang is not null order by 4
 
 
 
num nom est_enfant_de rang
15 Maurice 7 1
16 Gerard 15 2
18 Georgette 16 3
19 Germaine 16 3
20 Loic 16 3



III-19 Autres types de données : les objets spatiaux

  Avec l'extension objet de OpenIngres, on dispose d'une bibliothèque de nouveaux types de données, les objets spatiaux, qui comprennent le point (point), la boîte (box), le segment de droite (lseg), la ligne et la ligne longue (line et long line), le polygone et le polygone long (polygon et long polygon), le cercle (circle).

Ces types peuvent être utilisés dans les définitions d'attributs de tables. Il leur correspond des opérateurs et des fonctions qui permettent de les manipuler et de faire des opérations de type spatial.
 

III-19-1 Le type point "point"


  Il consiste en 2 valeurs de coordonnées x et y, chacune étant du type float8.

Exemple d'utilisation :

création d'une table :

create table point_table( id char(2), obj point); insertion dans une table : insert into point_table values ('AA', '(1,1)');

insert into point_table values ('BB', '(0.0,12.37)');

insert into point_table values ('CC', '(1234,-54321)');


III-19-2 Le type boîte "box"


  Une boîte est un rectangle dont les côtés sont parallèles aux axes du système de coordonnées. Elle est définie par deux points qui sont le point inférieur gauche et le point supérieur droit, par exemple ((1, 2.25), (5, 6,5)).

Exemple d'utilisation :

création d'une table :

create table box_table ( id char(2), obj box); insertion dans une table : insert into box_table values('A', '((0,0), (1,1))');

insert into box_table values ('B', '((-10,0), (10,1))');

insert into box_table values ('C', '((110,10),(211,21))');


III-19-3 Le type segment "lseg"


  Un segment est défini par deux éléments : le point début et le point fin, par exemple 

((1, 2), (3.45, -4.0)).

Exemple d'utilisation :

création d'une table :

create table lseg_table ( id char(1), obj lseg); insertion dans une table : insert into lseg_table values('A', '((0, 0), (1, 2))');

insert into lseg_table values ('B', '((-120, 0),(120,1))');

insert into lseg_table values ('C', '((11.3,10), (21.1, 2.1))');


III-19-4 Le type ligne "line"


  Une ligne est définie par deux parties : le nombre de points qu'elle comporte et le tableau des points. Pour définir un attribut de type line, on donnera sa dimension. Pour créer les données d'une ligne, on donnera les coordonnées de ses points.

Remarque : une ligne ne peut avoir plus de 124 points (taille maximale d'un tuple).

Exemple d'utilisation :

création d'une table :

create table line_table ( id char(2), obj line (3)); insertion dans une table : insert into line_table values ('L1', '((0, 0), (1,1), (2, 2))');

insert into line_table values ('L2', '((0.5, 0.5),(1.5,1.5), (2, 2))');

insert into line_table values ('L3', '((-0.4, -0.3),(1,1), (2, 2))');


III-19-5 Le type ligne longue "long line"

Une ligne longue permet d'étendre la taille maximale d'une ligne à 100 million de points environ, correspondant à un encombrement de 2Goctets.
  III-19-6 Le type polygone "polygon"


  Un polygone est défini par deux parties, comme le type line : le nombre de points qu'il comporte et le tableau des points. Mais les points doivent respecter la fermeture du polygone. Pour définir un attribut de type polygon, on donnera sa dimension. Pour créer les données d'un polygone, on donnera les coordonnées de ses points.

Remarque : un polygone ne peut avoir plus de 124 points (taille maximale d'un tuple).

Exemple d'utilisation :

création d'une table :

create table polygon_table ( id char(2), obj polygon (4)); insertion dans une table : insert into polygon_table values ('P1', '((0, 0), (1,1),(2, 2), (0, 0))');


III-19-7 Le type polygone long "long polygon"


  Un polygone long permet d'étendre la taille maximale d'un polygone à 100 million de points environ, correspondant à un encombrement de 2Goctets.
 

III-19-8 Le type cercle "circle"


  Un cercle est défini par deux éléments : le point centre du cercle et le rayon, le rayon étant de type float.

Exemple d'utilisation :

création d'une table :

create table circle_table ( id char(2), obj circle); insertion dans une table : insert into circle_table values ('C1', '((0, 0), 1)');

insert into circle_table values ('C2', '((1, 1), 10)');

insert into circle_table values ('C3', '((0, 0), 20)');


III-19-9 Tableau des formats des types spatiaux

Nom Format de stockage Etendue
point 2 flottants de 8 octets -1.0e+38 à 1.0 e+38

précision de 16 chiffres

lseg 2 points -1.0e38 à 1.0 e38

précision de 16 chiffres

line 1 entier

1 tableau de points

2 à 124

-1.0e+38 à 1.0 e+38

précision de 16 chiffres

box 2 points -1.0e+38 à 1.0 e+38

précision de 16 chiffres

polygon 1 entier 3 à 124

-1.0e+38 à 1.0 e+38

précision de 16 chiffres

circle 1 point
 
 

1 flottant

-1.0e3+8 à 1.0 e+38

précision de 16 chiffres

même que float

doit être > 0.0


  III-19-10 Les opérateurs spatiaux disponibles
 
  • les opérateurs de comparaison d'égalité = et <>
ils s'appliquent à 2 attributs de même type et comparent leur représentation interne;

ex : comparaison de 2 segments

((1, 2), (3, 4)) <> ((3, 4), (1, 2)) donnera vrai
  • les opérateurs spatiaux binaires : inside et intersects
inside (objet1, objet2) rend la valeur 1 si l'objet1 est contenu dans l'objet2 tableau des combinaisons de types valides pour l'opérateur inside :
 
point
box lseg line et 

long line

polygon et

long polygon

circle
point
non
oui non non oui oui
box
non
oui non non oui oui
lseg
non
oui non non oui oui
line et

long line

non
oui non non oui oui
polygon et

long polygon

non
oui non non oui oui
circle
non
oui non non oui oui
intersects (objet1, objet2) rend la valeur 1 si l'objet1 intersecte l'objet2; tous les types d'objets sont permis.
  III-19-11 Les fonctions disponibles sur les attributs de types spatiaux


  Il y a trois types de fonctions : 

  • les fonctions spatiales, telles que la fonction area, perimeter, etc. 
  • les fonctions de conversions spatiales 
  • les fonctions spatiales de conversions de types
  • les fonctions spatiales
area calcule la surface d'une boîte, d'un cercle, d'un polygone
length calcule la longueur d'une ligne, d'un segment
perimeter calcule le périmètre d'une boîte, d'un cercle, d'un polygone
distance calcule la distance entre 2 points
  • les fonctions de conversions spatiales
elles acceptent un type spatial et rendent, soit une valeur de type point, soit une valeur de type flottante (double) correspondant à la coordonnée x ou y:
point_x rend la coordonnée x d'un point
point_y rend la coordonnée y d'un point
box_ll rend le point inférieur gauche
box_ur rend le point supérieur droit 
line convertit un segment en ligne
bbox rend la boîte entourant l'objet
  • les fonctions spatiales de conversions de types, décrites par le tableau suivant :
Nom Opérande Type du résultat Description
bbox lseg

line

long line

polygon

long polygon

circle

box convertit l'opérande en une représentation interne de box. Les limites de la boîte sont définies par la paire de valeurs x, y minimales et maximales trouvées dans le type converti.
Box char

varchar

box convertit une chaîne de type char ou varchar en une représentation interne de box.
Char point

lseg

box

line

polygon

circle

char rend une représentation en chaîne de caractères de l'opérande
circle char

varchar

circle convertit une chaîne de type char ou varchar en une représentation interne de circle.
Line char

varchar

line convertit une chaîne de type char ou varchar en une représentation interne de line.
Long line char

varchar

long line convertit une chaîne de type char ou varchar en une représentation interne de long line.
Polygon char

varchar

polygon convertit une chaîne de type char ou varchar en une représentation interne de polygon.
Long polygon char

varchar

long polygon convertit une chaîne de type char ou varchar en une représentation interne de long polygon.
Lseg char

varchar

lseg convertit une chaîne de type char ou varchar en une représentation interne de lseg.
Point char

varchar

point convertit une chaîne de type char ou varchar en une représentation interne de point.
Varchar point

lseg

box

line

polygon

circle

varchar rend une représentation en chaîne de caractères de l'opérande (comme la fonction char).