SQL Server - La FAQConsultez toutes les FAQ

Nombre d'auteurs : 13, nombre de questions : 119, dernière mise à jour : 31 mai 2011  Ajouter une question

 

Question / réponses à tout ce que vous avez toujours voulu savoir sur Microsoft SQL Server sans jamais oser le demander


SommaireTrucs et Astuces en T-SQLFonctions (11)
précédent sommaire suivant
 

Toutes les fonctions sont disponibles à cette addresse : Fonctions temporelles

Mis à jour le 28 septembre 2005 Fabien Celaia

Utiliser la fonction encrypt()

Mis à jour le 28 septembre 2005 Fabien Celaia

Code tsql : Sélectionner tout
1
2
3
select *  
from MaTable  
where ChampMotDePasseCrypte=encrypt(@MaChaineNonCryptee)

Mis à jour le 28 septembre 2005 Fabien Celaia

Vous pouvez utiliser la fonction DatePart en usant de la commande SET DATEFIRST pour controller le premier jour de la semaine.

Code tsql : Sélectionner tout
1
2
3
4
5
SELECT CASE  
        WHEN DatePart( week, @Date1 ) = DatePart( week, @Date2)   
THEN 1 
        ELSE 0 
END

Mis à jour le 3 mai 2006 Fabien Celaia

APP_NAME renvoie le nom de l'application pour la session en cours si un nom a été défini par l'application.
Exemple :
L'exemple suivant vérifie si l'application cliente qui a initié ce traitement est une session de l'Analyseur de requêtes SQL.

Code tsql : Sélectionner tout
1
2
3
4
DECLARE @CurrentApp varchar(35) 
SET @CurrentApp = APP_NAME() 
IF (@CurrentApp <> 'MS SQL Query Analyzer') 
PRINT 'ce processus n'a pas été démarré par une cession de Query Analyzer.'

Mis à jour le 28 septembre 2005 WOLO Laurent

Il peut être important de connaître le nom de la station de travail qui à executer une instruction
d'insertion de données par exemple. Pour cela, nous faisons appel à la fonction HOST_NAME()
Exemple :

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
8
9
CREATE TABLE Orders 
( 
OrderID     INT        PRIMARY KEY, 
    CustomerID  NCHAR(5)   REFERENCES Customers(CustomerID), 
    Workstation NCHAR(30)  NOT NULL DEFAULT HOST_NAME(), 
    OrderDate   DATETIME   NOT NULL, 
    ShipDate    DATETIME   NULL, 
    ShipperID   INT        NULL REFERENCES Shippers(ShipperID) 
)

Mis à jour le 28 septembre 2005 WOLO Laurent

Code tsql : Sélectionner tout
SELECT DAY(DATEADD(d, -DAY(DATEADD(m,1,@Date)),DATEADD(m,1,@date))) AS DernierJourDuMois

Mis à jour le 9 août 2006 rudib

Petite procédure stockée permettant le scannage des colonnes susceptibles de contenir le champ.

Code tsql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
create proc [dbo].[fc_trouvetout] (@cherche as varchar(2000))  
as  
/* Auteur : Fabien Celaia 
 * Date   : 16.10.2007 
 */ 
begin  
 
declare @tb varchar(100), @co varchar(100), @sql nvarchar(500)  
 
select o.name TBL, c.name COL, 0 NBRE  
into #Result  
from sysobjects o  
inner join syscolumns c on c.id=o.id  
inner join  systypes t on t.xtype=c.xtype  
where c.length >= datalength (@cherche)  
and  t.name like '%char%'  
and o.type='U'  
 
declare cur cursor for select TBL, COL from #result -- for update  
 
open cur  
 
FETCH NEXT FROM cur INTO @tb, @co  
 
WHILE @@FETCH_STATUS = 0  
BEGIN  
 
set @sql = 'declare @i int  
select @i=count(*) from '+@tb +' where '+@co+' like ''%'+@cherche+'''  
if @i > 0  
        update #result set NBRE=@i where COL='''+@co+''' AND TBL = '''+@tb+''''  
 
exec sp_executesql @sql  
 
FETCH NEXT FROM cur INTO @tb, @co  
END  
 
close cur  
deallocate cur  
select * from #Result where NBRE>0  
drop table #Result  
end
Attention : selon la volumétrie de la base, la recherche peut être extrêmement longue et coûteuse.

Mis à jour le 16 octobre 2007 Fabien Celaia

Quelles sont les différences majeures entre une fonction SQL dite UDF (User Defined Function) et une procédure ?

Une fonction (ou UDF, user Define Fonction) est un programme destiné à fournir en sortie, une valeur scalaire ou une table (SELECT).

Les fonctions scalaires ne peuvent pas contenir :

  • de transaction (BEGIN TRANSACTION, COMMIT, ROLLBACK,
  • de sql dynamique (EXEC ('...')
  • d'ordre de mise à jour (INSERT, UPDATE, DELETE, MERGE)
  • d'ordre DDL (CREATE, ALTER, DROP), DCL (GRANT REVOKE)
  • un appel à une procédure (EXEC P...)
  • l'utilisation d'un cursor (DECLARE CURSOR, FETCH...)
  • de commande de débogage comme PRINT

Une fonction table peut contenir des ordres de mise à jour, mais ces commandes ne peuvent porter qu'uniquement sur la table en sortie.

Une procédure se créée par CREATE PROCEDURE et ses E/S sont :
  • des paramètres input et output
  • un éventuel jeu de résultat (voir même plusieurs)
  • une valeur de retour (code d'erreur)

Elle peut contenir tout code SQL, y compris :
  • transaction
  • mise à jour
  • SQL dynamique
  • cursor
  • commande DDL

Bien entendu, vous pouvez créer vos procédures dans différents schémas SQL que vous aurez préalablement créés.

Mis à jour le 24 mai 2009 SQLpro

Voici un problème complexe, comment "parser" une phrase avec, non pas un caractères de césure, mais un ensemble ? Cette fonction répond à cette demande en fournissant en sortie une table...

Cette fonction permet de découper une phrase selon de multiples caractère de césure.

Code sql : Sélectionner tout
1
2
@PHRASE : la phrase à découper  
@PARSEC : les caractères de césure
Code php : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
colonne 1 : POS la position du mot dans la phrase  
colonne 2 : MOT le mot  
colonne 3 : CHR le caractère de césure 
  
CREATE FUNCTION dbo.F_MULTIPARSE(@PHRASE VARCHAR(max),  
                                 @PARSEC VARCHAR(256))  
RETURNS @T TABLE (POS   INT,  
                  MOT   VARCHAR(128),  
                  CHR   CHAR(1))  
AS  
/******************************************************************************   
* Fonction table de découpage à césure multiple                               *  
*******************************************************************************   
* Fred. Brouard - http://SQLPro.developpez.com - www.sqlspot.com - 2009-04-17 *   
******************************************************************************/  
BEGIN  
-- effets de bord  
IF @PHRASE IS NULL RETURN;  
IF COALESCE(@PARSEC, '') = ''  
BEGIN  
   INSERT INTO @T VALUES (1, @PHRASE, NULL);  
   RETURN;  
END;  
-- variables locales  
DECLARE @C    CHAR(1),      -- lettre analysée  
        @MOT  VARCHAR(128), -- mot découpé  
        @I    INT,          -- boucle sur phrase  
        @J    INT,          -- boucle sur caractère de césure    
        @JMIN INT,          -- premier caractère de césure dans phrase  
        @IC   INT,            
        @M    INT;  
SELECT @I = 1, @M = 1;  
-- boucle sur phrase  
WHILE @I <=  LEN(@PHRASE)  
BEGIN  
   SET @J = 1;  
   SET @JMIN = NULL;  
-- boucle sur la liste des caractères de césure     
   WHILE @J <= LEN(@PARSEC)  
   BEGIN  
      SET @C = SUBSTRING(@PARSEC, @J, 1);  
      SET @IC = CHARINDEX(@C, @PHRASE)  
      IF @IC > 0  
         SET @JMIN = CASE WHEN @JMIN < @IC THEN @JMIN ELSE @IC END;  
      SET @J = @J + 1  
   END;  
-- récupération de l emplacement de la césure la plus proche  
   IF @JMIN IS NOT NULL  
   BEGIN  
      SET @C = SUBSTRING(@PHRASE, @JMIN, 1);  
      SET @MOT = SUBSTRING(@PHRASE, 1, @JMIN -  1);  
      SET @PHRASE =  SUBSTRING(@PHRASE, @JMIN + 1, LEN(@PHRASE) - @JMIN);  
      IF @MOT <> ''  
         INSERT INTO @T VALUES (@M, LTRIM(@MOT), @C);  
      SET @M = @M + 1;  
   END  
   SET @I = @I + 1;  
END  
-- insertion du dernier mot  
IF @PHRASE <> ''  
   INSERT INTO @T VALUES (@M, LTRIM(@PHRASE), NULL);  
RETURN  
END   
GO
Exemple :

Code sql : Sélectionner tout
1
2
SELECT *  
FROM   dbo.F_MULTIPARSE('toto, tata-titi', '-,')
Code : Sélectionner tout
1
2
3
4
5
POS         MOT                  CHR  
----------- -------------------- ----   
1           toto                 ,      
2           tata                 -      
3           titi                 NULL
Si vous voulez découper avec le caractère espace (blanc) il ne faut pas le placer en fin du paramètre @PARSEC sinon il sera ignoré du fait du type VARCHAR. Si vous ne voulez parser que sur le blanc, rajouter à la suite du blanc un caractère non imprimable (ASCII inférieur à 20). Par exemple CHAR(8).

Mis à jour le 24 mai 2009 SQLpro

Juste une petite fonction SQL pour calculer la date de pâques et toutes les dates qui en découlent (Lundi de Pâques, Ascension, Pentecôte et Lundi de Pentecôte).

L'algorithme utilisé pour ce calcul est celui d'Oudin.

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- fonction de calcul de la date de pâques  
CREATE FUNCTION dbo.F_CALCULE_PAQUES (@AN INT)  
RETURNS DATE  
/******************************************************************************   
* fonction table de calcul de la date de pâques                               *  
*******************************************************************************   
* Fred. Brouard - http://SQLPro.developpez.com - www.sqlspot.com - 2009-03-20 *   
******************************************************************************/   
AS  
BEGIN  
   DECLARE @G INT, @C INT, @C4 INT, @E INT, @H INT, @K INT, @P INT, @Q INT,   
        @I INT, @B INT, @J1 INT, @J2 INT, @R INT;  
   SELECT @G = @AN % 19, @C = @AN / 100, @B = (@AN / 4) + @AN;  
   SELECT @C4 = @C / 4, @E = ((8 * @C) + 13) / 25;  
   SELECT @H = ((19 * @G) + @C - @C4 - @E + 15) % 30;  
   SELECT @K = @H / 28, @P = 29 / (@H + 1), @Q = (21 - @G) / 11;  
   SELECT @I = (((@K * @P * @Q) - 1 ) * @K) + @H;  
   SELECT @J1 = @B + @I + 2 + @C4 - @C;  
   SELECT @J2 = @J1 % 7;  
   SELECT @R = 28 + @I - @J2;  
   RETURN DATEADD(day, @R - 1, CAST(CAST(@AN AS CHAR(4)) +'0301' AS DATE));  
END  
GO
Code sql : Sélectionner tout
SELECT dbo.F_CALCULE_PAQUES (2009);
Les autres dates des jours fériés mobiles sont calculées d'après la date de Pâque comme suit :
  • Lundi de pâques = Pâques + 1
  • Pentecôte = Pâques + 50
  • Lundi de Pentecôte = Pâques + 51
  • Ascension = Pâques 40 (jeudi)

Exemple d'utilisation :

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WITH   
T AS  
(SELECT DISTINCT dbo.F_CALCULE_PAQUES(2009) AS P  
),  
D AS  
(SELECT P, 'Pâques' AS NOM   
 FROM   T  
 UNION ALL  
 SELECT DATEADD(day, 1, P), 'Lundi de Pâques'  
 FROM   T  
 UNION ALL  
 SELECT DATEADD(day, 40, P), 'Ascension'  
 FROM   T  
 UNION ALL  
 SELECT DATEADD(day, 50, P), 'Pentecôte'  
 FROM   T  
 UNION ALL  
 SELECT DATEADD(day, 51, P), 'Lundi de Pentecôte'  
 FROM   T)  
SELECT *  
FROM   D;
Code : Sélectionner tout
1
2
3
4
5
6
7
P          NOM  
---------- ------------------  
2009-04-12 Pâques  
2009-04-13 Lundi de Pâques  
2009-05-22 Ascension  
2009-06-01 Pentecôte  
2009-06-02 Lundi de Pentecôte

Mis à jour le 24 mai 2009 SQLpro

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Contacter le responsable de la rubrique SQL-Server