Bonjour,
est que vous pouvez m'aider pour ecrire une fonction avec l'instruction CREATE FUNCTION comme la fonction d'agregation COUNT.
Merci.
Version imprimable
Bonjour,
est que vous pouvez m'aider pour ecrire une fonction avec l'instruction CREATE FUNCTION comme la fonction d'agregation COUNT.
Merci.
Vous ne pouvez pas créer des fonctions d'agrégation en transact SQL.
Pour créer des fonctions d'agrégation, il faut les coder en .net.
Exemple :
Puis construire la DDL et l'intégrer en transaction SQL :Code:
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 using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft .SqlServer.Server; using Microsoft.SqlServer.Server; [Serializable] [SqlUserDefinedAggregate(Format.Native,Name = "AggreagateAny")] public struct AggreagateAny { private int Counter; // compteur public void Init() { Counter = 1; // initialisation } public void Accumulate(object Value) { if (Value == 0) // si zero, met 0 Counter = 0; } public void Merge(Count0 Group) { this.Counter = this.Counter * Group.Counter; // a la fusion on multiplie } public SqlString Terminate() { return new SqlString(Counter.ToString()); //retourne le résultats } }
A +Code:
1
2
3
4
5 CREATE ASSEMBLY .... CREATE AGGREGATE UDA_ANY (@bool BIT) RETURNS BIT EXTERNAL NAME ...
Est ce que une fonction dans le T-SQL peut prendre une table comme un paramètre d’entrée?
donner un exemple s'il vous plaît.
et Merci M.SqlPro
Non.
A +
Bonjour,
C'est possible avec les paramètres de type TABLE introduits avec SQL Server 2008.
Pour faire cela vous devez d'abord créer votre type :
Et voici une fonction pour l'exemple :Code:
1
2
3
4
5 CREATE TYPE dbo.table_valued_parameter AS TABLE ( col1 INT )
Voici un exemple d'utilisation :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 CREATE FUNCTION dbo.fn_tvp (@tvp table_valued_parameter READONLY) RETURNS bit AS BEGIN DECLARE @b bit = 0 IF EXISTS ( SELECT * FROM @tvp WHERE col1 = 0 ) SET @b = 1 RETURN @b END
Retourne 0.Code:
1
2
3
4
5 DECLARE @tvp dbo.table_valued_parameter INSERT INTO @tvp VALUES (1), (2), (3) SELECT dbo.fn_tvp(@tvp)
Mais je ne les utiliserai pas pour deux raisons :
- Les fonctions définies par l'utilisateur sont contre-performantes parce qu'elles ne sont pas ensemblistes.
En effet, elles sont appelées pour chaque ligne du résultat.
- la variables de type TABLE ont un cardinal qui est toujours estimé à 1, ce qui peut rendre votre requête contre-performante, surtout si vous y stockez un grand nombre de valeurs.
Vous pouvez vous passez de cela, surtout dès SQL Server 2005 qui a introduit les expressions de table commune (CTE dans la littérature).
Dites-nous en plus sur ce que vous avez besoin d'implémenter; je suis sûr que nous trouverons une meilleure solution que la fonction ;)
@++ ;)
Merci beaucoup M. elsuket,
j'ai choisi les fonctions parce que je veux un objet qui accepte le nom d'une table ou bien la table elle-même et un nombre entier, pour retourner le nombre de lignes de cette table.
Hello,
une solution (qui fonctionne à partir de SQL Server 2000) si chaque table est indexée
Code:
1
2
3
4
5
6
7
8
9
10
11 CREATE FUNCTION dbo.getNbLignes (@tablename sysname) RETURNS BIGINT AS BEGIN RETURN ( SELECT max(rowcnt) FROM sysindexes WHERE id = OBJECT_ID(@tablename) GROUP BY id ) END GO
Pour SQL Server 2005 et ultérieur, vous pouvez écrire :
Qui vous retournera -1 si la table n'existe pas, et le nombre de lignes de la table si elle existe, qu'elle soit indexée ou non.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 CREATE FUNCTION Fn_GetTableRowCount (@_table_name sysname) RETURNS bigint AS BEGIN DECLARE @table_row_count bigint = -1 SELECT @table_row_count = PS.row_count FROM sys.dm_db_partition_stats AS PS JOIN sys.tables AS T ON PS.object_id = T.object_id WHERE PS.index_id BETWEEN 0 AND 1 AND T.name = @_table_name RETURN @table_row_count END
C'est inspiré du billet que j'ai publié là-dessus ;)
@++ ;)