2017-12-28 53 views
0

Ich habe folgende SQL-Abfrage.SQL Parameter Problem

DECLARE @OID NVARCHAR(MAX) = '(98,99,100,101,102,103,104,105)' 

SELECT 
    Name = (SELECT [Name] 
      FROM Point 
      WHERE CAST(OID AS NVARCHAR(10)) = Point), 
    Timestamp, 
    ValueNumeric 
FROM 
    [IngeniousRPM_Bridge].[dbo].[Value] 
WHERE 
    CAST(Point AS NVARCHAR(10)) IN (98,99,100,101,102,103,104,105) 
    AND [Timestamp] BETWEEN '2017-11-01' AND '2017-11-30' 
    AND ValueNumeric IS NOT NULL 

Die obige Abfrage funktioniert gut, wenn @OID hart codiert ist, aber wenn ich versuche, einen @OID Wert zu übergeben, wie unten gezeigt er keinen Wert in der Tabelle zurückgibt. Schließlich muss ich die gespeicherte Prozedur erstellen und @OID Wert übergeben.

DECLARE @OID NVARCHAR(MAX) = '(98,99,100,101,102,103,104,105)' 

SELECT 
    Name = (SELECT [Name] 
      FROM Point 
      WHERE CAST(OID AS NVARCHAR(10)) = Point), 
    Timestamp, 
    ValueNumeric 
FROM 
    [IngeniousRPM_Bridge].[dbo].[Value] 
WHERE 
    CAST(Point AS NVARCHAR(10)) IN (@OID) 
    AND [Timestamp] BETWEEN '2017-11-01' AND '2017-11-30' 
    AND ValueNumeric IS NOT NULL 
+0

Das ist Nicht-Standard-SQL. Welches [DBMS] (https://en.wikipedia.org/wiki/DBMS) Produkt verwenden Sie? "SQL" ist nur eine Abfragesprache, nicht der Name eines bestimmten Datenbankprodukts. –

+1

Die Variable @OID, die Sie übergeben, ist ein Varchar und wird in der IN-Klausel als solche behandelt. Je nachdem, welche Version von SQL Sie verwenden, kann diese Stapelüberlaufantwort Ihnen helfen, https://stackoverflow.com/questions/29538697/create-t-sql-function-with-table-parameter, falls nicht, lassen Sie uns bitte wissen, welche SQL und Version Sie verwenden. – SteveB

+0

Ich benutze MS SQL Server 2012 – Learner

Antwort

0

Sie müssen wie dieses Ich

SELECT 98 OID, 'Test' OidTest, GETDATE() [TimeStamp] 
INTO #MyTable 

DECLARE @OID nvarchar(MAX)='98,99,100,101,102,103,104,105' 
DECLARE @dyn nvarchar(MAX) 

SELECT @dyn = 'SELECT * FROM #MyTable WHERE OID IN (' + @OID +') and [Timestamp] between ''2017-11-01'' and ''2017-12-30''' 

exec (@dyn) 
-1

etwas tun, kann nicht Kommentare zur Zeit hinzufügen ...

Wenn Sie die Klammer aus dem varchar Zeichenfolge ist Ihre parametrisierte Version entfernen Arbeit? im Wesentlichen sagen Sie "IN ((98,99,100,101,102,103,104,105))", wo ich denke, was Sie wollen, ist "IN (98,99,100,101,102,103,104,105)"?

Ich würde auch nicht verketteten Strings als Vorschlag verwenden, insbesondere wenn Sie eine gespeicherte Prozedur verwenden möchten, die einen @ OID-Wert akzeptiert ... Sie offen für SQL Injection-Schwachstellen. Verwenden Sie stattdessen sp_executesql innerhalb Ihrer gespeicherten Prozedur und übergeben Sie Ihre Parameter. Wenn Sie Ihren Code kopieren, sieht das in etwa so aus:

UPDATE: Die Abfrage wurde aktualisiert, um Datumsparameter einzubeziehen.

declare @OID nvarchar(MAX)='98,99,100,101,102,103,104,105'; 
declare @sql nvarchar(max); 
declare @startDate datetime; 
declare @endDate datetime; 
SET @sql = N' 
      SELECT Name= (select [Name] from Point where CAST(OID AS 
      NVARCHAR(10)) 
      =Point), 
      Timestamp, 
      ValueNumeric 
      FROM [IngeniousRPM_Bridge].[dbo].[Value] where CAST(Point AS 
      NVARCHAR(10)) 
      In (' + @OID + ') and [Timestamp] between @startDateIN and 
      @endDateIN and 
      ValueNumeric is not null'; 
EXEC sp_executesql @sql 
        ,N'@startDateIN datetime, @endDateIN Datetime' 
        ,@startDateIN = @startDate 
        ,@endDateIN = @endDate; 
+1

Dies wird überhaupt nicht funktionieren. Sie können Parameter auf diese Weise nicht verwenden. – Jonny

+0

funktioniert immer noch nicht. – Learner

+0

sehr guter Punkt ... es wird nicht funktionieren, weil es eine Komma getrennte Liste ist ... Ich habe die Abfrage bearbeitet, aber mein Kommentar steht immer noch über die Verwendung von sp_executesql, vor allem, wenn Sie Benutzereintrag analysieren. – DimUser