Größte gemeinsame Teiler zweier Zahlen

Posted on Aug 3, 2004 von in SQL Server

Dies ist die Adaption der Excel Funktion GGT().

CREATE FUNCTION dbo.ggt(@zahl1 int, @zahl2 int) 
RETURNS INT
AS
BEGIN
DECLARE @zahl3 INT
SET @zahl3=1
WHILE (@zahl3 <> 0)
BEGIN
SET @zahl3=@zahl1 % @zahl2
SET @zahl1=@zahl2
SET @zahl2=@zahl3
END
RETURN @zahl1
END
GO
SELECT dbo.ggt(24,36)
DROP FUNCTION dbo.ggt

-----------
12

(1 row(s) affected)

Dynamisches SQL innerhalb einer Funktion

Posted on Aug 2, 2004 von in SQL Server

Dynamisches SQL kann nicht innerhalb einer Funktion ausgeführt werden. Genausowenig können Stored Procedures aufgerufen werden. Der einzige Workaround hier ist, eine andere Logik anzuwenden, um um den dynamischen Teil herumzukommen. So führt z.B. folgendes zu einem Fehler:

Ganze Geschichte »

Sequentielle Nummerierung eines Resultsets

Posted on Aug 2, 2004 von in SQL Server

Eine beliebte Frage mit unzähligen Antworten. Meine Lieblingsantwort darauf ist, dies in der Präsentationsschicht seiner Anwendung zu machen. IMHO ist dies Aufgabe des Clients, nicht des Servers. Wenn es aber unbedingt in T-SQL gemacht werden soll, kann man folgendes machen:

USE PUBS
GO
SELECT
(
SELECT COUNT(*)
FROM Authors
WHERE au_id <= A.au_id
) AS Lfd_Nr
, au_lname, au_fname
FROM
Authors AS A
ORDER BY
Lfd_Nr
GO

Lfd_Nr au_lname au_fname
----------- ---------------------------------------- --------------------
1 Hello World Johnson
2 Green Marjorie
3 Carson Cheryl
4 O'Leary Michael
5 Straight Dean
6 Smith Meander
7 Bennet Abraham
8 Dull Ann
9 Gringlesby Burt
10 Locksley Charlene
11 Greene Morningstar
12 Blotchet-Halls Reginald
13 Yokomoto Akiko
14 del Castillo Innes
15 DeFrance Michel
16 Stringer Dirk
17 MacFeather Stearns
18 Karsen Livia
19 Panteley Sylvia
20 Hunter Sheryl
21 McBadden Heather
22 Ringer Anne
23 Ringer Albert

(23 row(s) affected)

Bei umfangreichen Resultsets kann die obige Methode schon mal einige Zeit in Anspruch nehmen. Ist also nur bedingt empfehlenswert. Eine Alternative ist vielleicht die Verwendung der IDENTITY Funktion zusammen mit einer temporären Tabelle, so wie hier:

SELECT 
IDENTITY(INT,1,1) AS Lfd_Nr
, au_lname
, au_fname
INTO #authors
FROM authors
ORDER BY au_id

SELECT *
FROM #authors
ORDER BY Lfd_Nr

DROP TABLE #authors

Lfd_Nr au_lname au_fname
----------- ---------------------------------------- --------------------
1 Hello World Johnson
2 Green Marjorie
3 Carson Cheryl
4 O'Leary Michael
5 Straight Dean
6 Smith Meander
7 Bennet Abraham
8 Dull Ann
9 Gringlesby Burt
10 Locksley Charlene
11 Greene Morningstar
12 Blotchet-Halls Reginald
13 Yokomoto Akiko
14 del Castillo Innes
15 DeFrance Michel
16 Stringer Dirk
17 MacFeather Stearns
18 Karsen Livia
19 Panteley Sylvia
20 Hunter Sheryl
21 McBadden Heather
22 Ringer Anne
23 Ringer Albert

(23 row(s) affected)

In SQL Server 2005 ist dies übrigens einfacher durch die Implementierung von ROW_NUMBER().

sp_spaceused in Tabelle unleiten

Posted on Jul 29, 2004 von in SQL Server
USE PUBS 
GO
SET NOCOUNT ON
CREATE TABLE #TableSpace
(
	Name char(20)
	,RowCnt int
	,Reserved varchar(15)
	,Data varchar(15)
	,Index_Size varchar(15)
	,Unused varchar(15)
)
DECLARE @Table sysname
DECLARE TableCur 
	CURSOR FOR
	SELECT 
		Table_Name
	FROM 
		INFORMATION_SCHEMA.Tables
	WHERE 
		Table_Type = 'BASE TABLE'
	AND 
		OBJECTPROPERTY(OBJECT_ID(Table_Name),'IsMSShipped') = 0
	OPEN TableCur FETCH NEXT FROM TableCur INTO @Table

WHILE @@FETCH_STATUS = 0
	BEGIN
		INSERT #TableSpace EXEC sp_spaceused @Table
		FETCH NEXT FROM TableCur INTO @Table
	END
CLOSE TableCur
DEALLOCATE TableCur
SELECT * FROM #TableSpace
DROP TABLE #TableSpace
SET NOCOUNT OFF

Name                 RowCnt      Reserved        Data            Index_Size      Unused          
-------------------- ----------- --------------- --------------- --------------- --------------- 
__tmpTBLCOL          131         80 KB           16 KB           8 KB            56 KB
authors              23          40 KB           8 KB            32 KB           0 KB
discounts            3           16 KB           8 KB            8 KB            0 KB
dup_authors          40          80 KB           16 KB           8 KB            56 KB
employee             43          40 KB           8 KB            32 KB           0 KB
jobs                 14          24 KB           8 KB            16 KB           0 KB
max_t                4           16 KB           8 KB            8 KB            0 KB
median               8           16 KB           8 KB            8 KB            0 KB
pub_info             8           160 KB          120 KB          16 KB           24 KB
publishers           8           24 KB           8 KB            16 KB           0 KB
roysched             86          32 KB           8 KB            24 KB           0 KB
sales                21          56 KB           8 KB            48 KB           0 KB
silly_one            0           0 KB            0 KB            0 KB            0 KB
stores               6           24 KB           8 KB            16 KB           0 KB
tableCounts          15          16 KB           8 KB            8 KB            0 KB
titleauthor          25          56 KB           8 KB            48 KB           0 KB
titles               18          40 KB           8 KB            32 KB           0 KB
Trace_Table_Name     0           0 KB            0 KB            0 KB            0 KB
vals                 127         24 KB           8 KB            16 KB           0 KB
x                    2           16 KB           8 KB            8 KB            0 KB

Danke an Jonathan van Houtte für das Originalskript.
Um sicherzustellen, dass RowCnt aktuell ist, sollte man vorher

DBCC UPDATEUSAGE(0) WITH COUNT_ROWS

ausführen.

Fakultät einer Zahl

Posted on Jul 26, 2004 von in SQL Server
CREATE FUNCTION dbo.fakultät(@n DECIMAL(38,0))
RETURNS DECIMAL(38,0)
AS
BEGIN
DECLARE @tmp DECIMAL(38,0)
IF (@n <= 1)
SELECT @tmp = 1
ELSE
SELECT @tmp = @n * dbo.fakultät(@n - 1)
RETURN @tmp
END
GO
SELECT dbo.fakultät(10)
DROP FUNCTION dbo.fakultät

----------------------------------------
3628800

(1 row(s) affected)

Spielt man dieses Spielchen weiter, wird man feststellen, dass man bei Zahlen grösser als 32, folgende Meldung erhält:

Server: Nachr.-Nr. 217, Schweregrad 16, Status 1,  Prozedur fakultät, Zeile 9
Die maximale Schachtelungsebene für .... (Limit ist 32).

Man wird auch feststellen, dass bei Input von 32 eine Abweichung zu Excel existiert.

Steigung einer Geraden

Posted on Jul 26, 2004 von in SQL Server
DECLARE @x1 FLOAT
DECLARE @x2 FLOAT
DECLARE @y1 FLOAT
DECLARE @y2 FLOAT

SELECT @x1 = 1, @x2 = 2, @y1 = 1, @y2 = 2
SELECT (@y2-@y1)/(@x2-@x1)

-----------------------------------------------------
1.0

(1 row(s) affected)

Oder als UDF

CREATE FUNCTION dbo.steigung(@y1 FLOAT,@y2 FLOAT, @x1 FLOAT, @x2 FLOAT)
RETURNS FLOAT
AS
BEGIN
RETURN (@y2-@y1)/(@x2-@x1)
END
GO

SELECT dbo.steigung(1,2,1,2)
DROP FUNCTION dbo.steigung


-----------------------------------------------------
1.0

(1 row(s) affected)

Postleitzahlen überprüfen

Posted on Jul 22, 2004 von in SQL Server

Hier ist eine Lösung mit Hilfe einer UDF:

Ganze Geschichte »

Postleitzahlen überprüfen

Posted on Jul 22, 2004 von in SQL Server

Hier ist eine Lösung mit Hilfe einer UDF:

Ganze Geschichte »