Fragensteller
SQL Funktion mehrere Rückgabewerte

Frage
Alle Antworten
-
Hi,
ähm. Genau so, wie Du es geschrieben hast.
Was genau soll denn in welchem Format zurückgegeben werden?
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Guten Tag,
Ich möchte eine Funktion schreiben, der alle Zeilen einer Spalte zurückgibt. Wie kann man das machen?
Eine zweite Frage:
SELECT * FROM [@database_name].[dbo].[hourly_rates]
Wissen Sie wieso das nicht funktioniert?
Mit freundlichen Grüßen,
Webdesigner01
- Bearbeitet Webdesigner01 Freitag, 1. März 2013 15:14
-
Hi,
um alle Zeilen einer Spalte zurückzugeben, schreibt man genau das, was Du in deinem ersten Posting angegeben hast.
SELECT <Spalte> FROM <Tabelle>
Objektnamen können nicht durch Parameter ersetzt werden. Also weder die Datenbank und das Schema, noch die Tabelllen- oder Spaltennamen.
Eine Möglichkeit ist dynamisches SQL. Also die Erstellung des SQL Statements als String und das ausführen per EXEC( @Variable ) bzw. sp_executesql.
Es sei aber die Frage erlaubt, warum Du das so machen willst. In vielen Fällen ist es unnötig und kontrakproduktiv. Schau Dir hierfür auch mal diesen Beitrag an:
http://www.insidesql.org/blogs/frankkalis/2004/07/16/dynamisches-sql-fluch-und-segen
Dort findest Du auch Beispiele, wie Du dynamische SQL Statements erzeugen und ausführen kannst.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Guten Tag,
Vielen Dank für die Antwort.
Funktion
ALTER FUNCTION dbo.ausgaben(@database_name As varchar(max)) RETURNS float AS BEGIN RETURN( SELECT SUM([euro/hour] FROM [@database_name].[dbo].[ausgaben]);
Wie würde das jetzt ausschauen?
Mit freundlichen Grüßen,
Webdesigner01
-
Hi,
schau dir bitte den verlinkten Artikel an. Da steht das drin.
Ein wenig Eigeninitiative solltest Du schon zeigen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Guten Tag
code:
ALTER FUNCTION dbo.ausgaben() RETURNS float AS BEGIN DECLARE @sql nvarchar(4000), @min varchar(20) SELECT @sql = N'Select [task_id] FROM [test].[dbo].[test]' EXEC sp_executesql @sql, N'@min varchar(20) OUTPUT', @min OUTPUT RETURN( @min )END;
Wieso funktioniert das nicht?
Error: Meldung 557, Ebene 16, Status 2, Zeile 1
Nur Funktionen und einige erweiterte gespeicherte Prozeduren können innerhalb einer Funktion ausgeführt werden.
Mit freundlichen Grüßen,
Webdesigner01
-
Hi,
als T-SQL Funktion geht das nicht. Siehe bspw:
http://www.insidesql.org/blogs/frankkalis/2004/08/02/dynamisches-sql-innerhalb-einer-funktion
Aber warum gerade eine Funktion? Das Ganze sieht mir sehr zusammengewürfelt aus. Rückgabe Float, Rückgabeparameter ist aber varchar, ein Statement, welches keinen Sinn ergibt (im Bezug auf die Rückgabe), ...
Was genau willst Du überhaupt machen? Wenn man das weiß, kann man dir evtl. auch besser helfen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hi,
ich wollte auch mal irgendwas schreiben, was mir irgendwie irgendwas macht und mir das dann wieder irgendwie doppelt zurückgibt. Hab ich auch nicht hinbekommen :) (Nicht böse gemeint :)
Soll heißen, so einfach drauflos "entwickelt" kann das auch nie was werden.
Beschreib bitte mal deine Tabellenstruktur. Also die Definition der Tabelle, in der die Daten stehen.
Gib uns dazu ein paar Beispieldatensätze und das gewünschte Ergebnis deiner Abfrage.
Bitte gar nicht erst versuchen, das irgendwie mit Worten zu umschreiben. Klare Fakten sind hier sehr viel besser geeignet um die helfen zu können.
Also bspw. so:
[Tabelle Ausgaben]
ID int Primärschlüssel
Datum date
Betrag floatAlternativ auch das CREATE TABLE Statement dazu, bei größeren Tabellen ist das ggfs. besser.
[SQL Statement]
CREATE TABLE [dbo].[Ausgaben]( [ID] [int] IDENTITY(1,1) NOT NULL, [Datum] [date] NOT NULL, [Betrag] [float] NULL, CONSTRAINT [PK_Ausgaben] PRIMARY KEY CLUSTERED ( [ID] ASC ) ) ON [PRIMARY]
[Beispieldaten]
ID Datum Betrag 1 2013-02-01 20 2 2013-02-01 30 3 2013-02-01 20 4 2013-03-01 10 5 2013-03-01 15
[Gewünschtes Ergebnis]
2013-02-01 70 2013-03-01 25
In dem Fall würde das benötigte SQL Statement bspw. so aussehen:
SELECT Datum, SUM( Betrag ) AS SummeAusgaben FROM Ausgaben GROUP BY Datum
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Freitag, 1. März 2013 21:16
- Als Antwort markiert Webdesigner01 Samstag, 2. März 2013 14:28
- Tag als Antwort aufgehoben Webdesigner01 Sonntag, 3. März 2013 12:09
- Als Antwort vorgeschlagen Stefan FalzModerator Mittwoch, 27. März 2013 22:36
-
Hallo Webdesigner,
aus Deinem Coding geht hervor, dass u. a. die Relation selbst eine Variable sein soll. Dies geht in Funktionen nicht:
http://msdn.microsoft.com/de-de/library/ms186755.aspxSofern Du tatsächlich die Relation selbst als Variable übergeben möchtest, kannst Du das nur durch zwei Lösungsansätze erreichen:
- Verwendung einer Stored Procedure
- Verwendung einer CLR-Function
Die Verwendung einer CLR-Funktion halte ich in Hochverfügbarkeitsumgebungen für fragwürdig - Gleiches gilt für Sicherheitsumgebungen (Banken, Versicherungen, ...)
Die Verwendung einer Stored Procedure wird in diesem Fall die einzige Lösung sein. Hierzu hat Frank aber schon mit einem Link auf die Sicherheitsrisiken (SQL Injection) hingewiesen. Sofern Du dieses Risiko tragen möchtest, kann man das wie folgt lösen:
USE tempdb GO -- Erstellen zweier Tabellen für die unterschiedlche Verwendung IF OBJECT_ID('dbo.firsttable', 'U') IS NOT NULL DROP TABLE dbo.firsttable GO IF OBJECT_ID('dbo.secondtable', 'U') IS NOT NULL DROP TABLE dbo.secondtable GO CREATE TABLE dbo.firsttable ( id int not null identity (1, 1) PRIMARY KEY CLUSTERED, col1 char(20) NOT NULL DEFAULT ('just a column'), col2 char(30) NOT NULL DEFAULT ('just a second column') ); CREATE TABLE dbo.secondtable ( id int not null identity (1, 1) PRIMARY KEY CLUSTERED, col1 int NOT NULL DEFAULT (rand() * 10000), col2 int NOT NULL DEFAULT (rand() * 1000), col3 AS col1 * col2 ); -- Befüllen der Tabellen mit ein paar Daten SET NOCOUNT ON GO INSERT INTO dbo.firsttable DEFAULT VALUES GO 100 INSERT INTO dbo.secondtable DEFAULT VALUES GO 100 --SELECT * FROM dbo.firsttable; --SELECT * FROM dbo.secondtable; GO -- Erstellen einer Stored Procedure für die Anforderungen IF OBJECT_ID('dbo.myproc', 'P') IS NOT NULL DROP PROC dbo.myproc GO CREATE PROC dbo.myproc @table_name sysname AS SET NOCOUNT ON -- Sollte die Relation nicht vorhanden sein, Fehler! IF OBJECT_ID(@table_name) IS NULL BEGIN RAISERROR ('Eine Tabelle %s existiert nicht', 0, 1, @table_name) WITH NOWAIT RETURN END DECLARE @stmt nvarchar(4000) SET @stmt = 'SELECT * FROM ' + @table_name + ';' EXEC sp_executeSQL @stmt; SET NOCOUNT OFF GO -- Test EXEC dbo.myproc 'dbo.firsttable'
Der Code ist relativ trivial - zunächst werden zwei Tabellen erstellt, die mit jeweils 100 Testdaten gefüllt werden. Anschließend erstelle ich eine Prozedur, die mittels sp_executeSQL einen SELECT auf die - als Parameter - übergebene Tabelle übergibt.
Bezüglich der von DIr geforderten "Berechnung" schau' Dir bitte mal die Tabelle dbo.secondtable an - in ihr ist das dritte Attribut eine Berechnung aus col1 und col2. Sofern Du nach berechneten Werten suchst, muß die Berechnung PERSISTED sein, um dieses Attribut mit einem Index versehen zu können.
Problem einer Prozedur in Gegensatz zu einer Funktion... - sie kann nicht in einem SELECT-Konstrukt verwendet werden!
Da jedoch nicht genau klar ist, was Du eigentlich machen möchtest, mußt Du schon etwas mehr Informationen bereitstellen.
Weitere Information zu den von mir angesprochenen Themen:
sp_executeSQL: http://msdn.microsoft.com/de-de/library/ms188001.aspx
persisted columns: http://msdn.microsoft.com/de-de/library/ms186241.aspxUwe Ricken
MCSE - SQL Server 2012
MCSA - SQL Server 2012
MCITP Database Administrator 2005
MCITP Database Administrator 2008
MCITP Microsoft SQL Server 2008, Database Development
db Berater GmbH
http://www-db-berater.de
SQL Server Blog (german only)- Als Antwort vorgeschlagen Stefan FalzModerator Mittwoch, 27. März 2013 22:36