简体   繁体   中英

Pass-through query with no value for optional parameter of T-SQL stored procedure

I have an Access form to edit records in a SQL Server 2008 R2 table.

There are 3 fields in the form which could be updated, but it may be that one or all 3 fields still are empty (Null), so the update is to set values the first time.

If the fields are NULL at the time it want to run the stored procedure and I add values for the first time the stored procedure fails with missing parameters.

The stored procedure looks like this:

ALTER PROCEDURE [dbo].[spAlarmprotokollaendern] 
    @FibuNr nvarchar(10)=Null,
    @FibuNr_alt nvarchar(10),
    @Preis decimal(5,2),
    @Preis_alt decimal(5,2)=null,
    @Alarmnummer int,
    @Kennung nvarchar(10),
    @Verrechnungsintervall int=null,
    @Verrechnungsintervall_alt int=null,
    @UserID int=null,
    @Objektname nvarchar(50)=null,
    @Objektstrasse nvarchar(60)=null,
    @ObjektPLZ nvarchar(6)=null,
    @Objektort nvarchar(50)=null,
    @Kostenstelle int, 
    @Objektnummer int

    UPDATE tblAlarmprotokolle 
    SET Fibunr = coalesce(@Fibunr, @Fibunr_alt), 
        Preis = coalesce(@Preis, @Preis_alt), 
        Verrechnungsintervall = coalesce(@Verrechnungsintervall, @Verrechnungsintervall_alt)
    WHERE 
        (Alarmnummer >= @Alarmnummer AND Kennung = @Kennung) 
        OR (abgerechnet = 0 AND Kennung = @Kennung)

I use coalesce to check any new value for the field and the set the old field. But if the old field is NULL then it fails.

How can I make this work?

Thanks Michael

The placeholder for an optional parameter value of a T-SQL stored procedure is the DEFAULT keyword. So, if your Access code is generating the following pass-through query call which is failing

EXEC dbo.spAlarmprotokollaendern '11150', '', 56.7, , 32627471 ...

then have it insert the DEFAULT keyword if the corresponding Access value is null:

EXEC dbo.spAlarmprotokollaendern '11150', '', 56.7, DEFAULT, 32627471 ...

Note that your EXEC statement must include the bare keyword DEFAULT , not the string value 'DEFAULT' , for example

Option Compare Database
Option Explicit

Sub SO32779923()
    Dim myFibunr, myFibunr_alt, myPreis, myPreis_alt, _
            myAlarmnummer, myKennung, _
            myVerrechnungsintervall, myVerrechnungsintervall_alt, _
            myUserID, myObjektname, myObjektstrasse, myObjektPLZ, _
            myObjektort, myKostenstelle, myObjektnummer
    myFibunr = "11150"
    myFibunr_alt = ""
    myPreis = 56.7
    myPreis_alt = Null
    myAlarmnummer = 32627471
    myKennung = "update_me"
    myVerrechnungsintervall = 4
    myVerrechnungsintervall_alt = Null
    myUserID = 0
    myObjektname = "x"
    myObjektstrasse = "x"
    myObjektPLZ = "x"
    myObjektort = "x"
    myKostenstelle = 0
    myObjektnummer = 0

    Dim spCall As String
    spCall = "EXEC dbo.spAlarmprotokollaendern " & _
            prepForSp(myFibunr) & ", " & _
            prepForSp(myFibunr_alt) & ", " & _
            prepForSp(myPreis) & ", " & _
            prepForSp(myPreis_alt) & ", " & _
            prepForSp(myAlarmnummer) & ", " & _
            prepForSp(myKennung) & ", " & _
            prepForSp(myVerrechnungsintervall) & ", " & _
            prepForSp(myVerrechnungsintervall_alt) & ", " & _
            prepForSp(myUserID) & ", " & _
            prepForSp(myObjektname) & ", " & _
            prepForSp(myObjektstrasse) & ", " & _
            prepForSp(myObjektPLZ) & ", " & _
            prepForSp(myObjektort) & ", " & _
            prepForSp(myKostenstelle) & ", " & _
            prepForSp(myObjektnummer)

    Debug.Print spCall

    Dim cdb As DAO.Database
    Set cdb = CurrentDb
    Dim qdf As DAO.QueryDef
    Set qdf = cdb.CreateQueryDef("")
    qdf.Connect = "ODBC;DSN=myDb"
    qdf.sql = spCall
    qdf.ReturnsRecords = False
    qdf.Execute
    Set qdf = Nothing
End Sub

Private Function prepForSp(thing As Variant) As String
    If IsNull(thing) Then
        prepForSp = "DEFAULT"
    Else
        Select Case VarType(thing)
            Case vbString:
                prepForSp = "'" & Replace(thing, "'", "''") & "'"
            Case vbDate:
                prepForSp = "'" & Format(thing, "yyyy-mm-dd Hh:Nn:Ss") & "'"
            Case Else
                prepForSp = CStr(thing)
        End Select
    End If
End Function

The Debug.Print statement displays

EXEC dbo.spAlarmprotokollaendern '11150', '', 56.7, DEFAULT, 32627471, 'update_me', 4, DEFAULT, 0, 'x', 'x', 'x', 'x', 0, 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM