2010-11-23 6 views
2

OK, das ist ein ziemlich einfaches Problem, aber ich bin neugierig: Was ist der beste Ansatz in Bezug auf Effizienz und Stil?Effizienter Weg, den Standardwert in t-sql zu wählen, wenn keine Ergebnisse gefunden werden

Ich muss oft Daten in MS SQL auswählen, aber bin auf der Suche nach einem einzigen Ergebnis. Wenn in der Datenbank keine Übereinstimmung vorhanden ist, möchte ich einen Standardwert zurückgeben.

Hier sind ein paar Ansätze, die ich nehmen:

Tun Sie es in der Code

--Regular Select in SQL 
SELECT myValue FROM dbo.SomeTable WHERE id = @id 


//In Data Access Layer 
using (IDataReader reader = cmd.ExecuteReader()) { 
    if (reader.Read()) { 
     return Convert.ToInt32(reader["myValue"]); 
    }else { 
     return 0; //return a default 
    } 
} 

Garantie einen Rückgabewert in SQL

--SQL stores in a variable and selects null value if available 
declare @myVal int 
select @myVal = myValue FROM dbo.SomeTable WHERE id = @id 

--return value or a default 
select ISNULL(@myVal,0) as myValue 


//In Data Access Layer 
return Convert.ToInt32(cmd.ExecuteScalar()); 

Gibt es eine elegantere Möglichkeit um dies zu tun? Oder ein effizienterer Weg?

Wenn nicht, welche von diesen würden Sie als eine bessere Praxis betrachten?

+0

Als allgemeine Regel würde ich sagen, dass der Standard in SQL zurückgegeben werden sollte, wenn Sie erwarten, dass alle anderen Systeme auf das Vorhandensein des Standards angewiesen sind. Wenn Sie nicht der Meinung sind, dass die meisten anderen Systeme in die eine oder andere Richtung gehen, sollte der Standard in der Client-App angewendet werden. Ich fürchte, ich kann nichts Genaueres anbieten, da ich mit TSQL nicht so gut bin. – FrustratedWithFormsDesigner

Antwort

2

Ich würde verwenden ISNULL(field, replacement_value_if_null) ist eine native T-SQL-Funktion und alles von der SQL-Server-Seite getan, so leichter zu debuggen.

Wenn jemand etwas Leistung hat, könnte das nützlich sein!

+1

'ISNULL' wird hier nicht funktionieren: Wenn keine Datensätze vorhanden sind, gibt die Abfrage ein leeres Recordset zurück, kein' NULL'-Wert. – Albireo

+0

@kappa: Gibt es eine Möglichkeit, eine leere Datensatzgruppe zu erkennen, wie Oracle 'NO_DATA_FOUND' Ausnahme? – FrustratedWithFormsDesigner

+1

+1 Für den Hinweis, wenn ISNULL funktioniert -> aber Sie könnten es im zweiten Teil einer Abfrage auf eine Variable verwenden, wie in der Frage – jkelley

0

Ich rate nur hier, aber: hast du es mit diesem Code versucht?

Nullable<Int32> Result = Command.ExecuteScalar(); 

if (Result == null) Result = 0; 

Edit: Jetzt habe ich es überprüft, und es funktioniert:

using (SqlConnection Connection = new SqlConnection()) 
{ 
    Connection.ConnectionString = ""; 
    Connection.Open(); 

    using (SqlCommand Command = Connection.CreateCommand()) 
    { 
     Command.CommandText = "select 'lol' as [column] where 1 = 0"; 

     String Result = (String) Command.ExecuteScalar(); 
    } 
} 

String ist null. So können Sie Nullable verwenden und Sie sind fertig.

0
((int?)cmd.ExecuteScalar()).GetValueOrDefault(); 

oder

((int?)cmd.ExecuteScalar())??0; 

Ist das, was Sie wollen, ich

+0

@DOK warum entfernen Sie den zweiten Teil meiner Antwort? –

+0

Ich habe nichts entfernt. Nur der erste Codeausschnitt war vorhanden, als ich die Codeformatierung zur Verbesserung der Lesbarkeit hinzufügte. Vielleicht haben wir beide gleichzeitig geschnitten? Sie können es in der Geschichte nachschlagen. – DOK

+0

Ok @DOK, danke –

0

denke, es ist nicht mir scheint, dass es viel Unterschied besteht darin, eine NULL oder Rückgabe eines Null zwischen der Rückkehr. In beiden Fällen muss Ihr Code noch etwas anderes tun, als wenn ein Ergebnis zurückgegeben würde. Du wirst immer noch eine if-else haben. Wenn ein Datensatz zurückgegeben wird, tun Sie dies, sonst tun Sie etwas anderes. Ich sehe also keinen großen Unterschied.

Ich würde Sie ermutigen, keine DataReader zu verwenden, um einen einzelnen Wert zurückzugeben. Es wäre besser, ExecuteScalar oder für bessere Leistung, ein Ausgabeparameter von einer gespeicherten Prozedur zu verwenden.

+0

Guter Rat zu ExecuteScalar - soweit abweichendes Verhalten basierend auf NULL oder einem Wert - ist die Absicht, Standardwerte in einer Situation wie Liefergebietszuschläge für den Versand bereitzustellen. Ich frage, ob es eine Übereinstimmung gibt, die auf der Postleitzahl basiert. Wenn nicht (Kein Ergebnis zurückgegeben), dann ist der Zuschlag Null, daher verhält sich das System in beiden Fällen konsistent. – jkelley

+0

@jkelley Wenn Sie den Standardwert in der gespeicherten Prozedur oder in Ihrem Code fest codieren, kann es für andere schwierig sein, sie in der Zukunft zu finden und zu ändern. Ich frage mich, ob es möglich wäre, den Standardwert in die Datenbank zu setzen und ihn anstatt oder zusätzlich zum angeforderten Wert zurückzugeben. Das würde den Standardwert einfacher finden und beibehalten. – DOK

-1

Ich benutze SQL SERVER 2008 R2. Ich hatte die gleiche Aufgabe zu erfüllen (einige Standardwerte zurückgeben, wenn kein realer Wert verfügbar ist) und ich habe die folgende Anweisung verwendet. Das Ergebnis ist der Standardwert, aber wenn ich 'Florida' anstelle von 'Englisch' hinzufügen würde, würde 'FL' als Zustandsabkürzung zurückgegeben werden:

--- deklarieren und geben Sie den Standardwert ein: declare @myVal varchar ( ) 10) = 'Kein Ergebnis' Wählen Sie @myVal = StateAbbr FROM dbo.Zustand, in dem Statusname =

--return Wert oder ein default ‚Englisch‘ @myVal

+0

Sie müssen Snippets bereitstellen –

0

wählen Es ist eine alte Post, aber bei Menschen suchen immer noch nach der Antwort, wie ich nicht allzu langer Zeit war:

Warum nicht du so:

IF(ISNUMERIC(@myVariable) = 1)... Wenn Ihre Variable ein numerischer ist.

Oder vielleicht IF(LEN(@myVariable) > 0)... für Strings.