从asp.net Web应用程序调用时存储过程调用失败,但在从SSMS调用时有效

时间:2014-06-16 12:42:06

标签: asp.net sql sql-server vb.net sql-server-2005

背景:

我们最近有一个项目,我们不得不在谷歌地图上绘制机构,但是使用地址来确定机构是否已经采取长期加载的方式。因此,我们决定将lat / lng存储在数据库中以对照机构记录。为此,我们创建了一个存储过程usp_web_kam_Geocode,调用GoogleMaps地理编码服务以返回随后存储的坐标。

我们在trg_Geocode之后tblInstitution创建了一个触发器INSERT, UPDATE,它提供了一些条件(bIncludeInKAMMap = 1,即要绘制它),然后调用usp_web_kam_Geocode并更新记录上的坐标。

问题:

将此触发器添加到表格后,当从网络应用程序调用时,对usp_web_InsertUpdateInstitution(负责插入和更新tblInstitution的任何调用都会失败而不会出现错误

我们已使用SQL Server Profiler跟踪此usp_web_InsertUpdateInstitution的调用,该调用产生以下内容:

enter image description here

declare @p1 int
set @p1=149078313
exec usp_web_InsertUpdateInstitution @lInstitutionID=@p1 output,@lRegionID=132,@TOREFMadisunNumber=N'',@sSageNumber=N'',@sName=N'Replication Test Changed',@Xaddress=N'',@sPostCode=N'GU97DR',@sPhone=N'',@sFax=N'',@lInstitutionTypeID=14,@sNote=N'',@lModifiedByID=0,@sAddress1=N'',@sAddress2=N'',@sAddress3=N'',@sTown=N'',@sCounty=N'',@TOREFCountry=N'',@sWebsite=N'',@lDistributorID=2,@XFCRef=0,@sSICCode=N'',@lEmployees=0,@sSource=N'',@bKeyAccount=0,@TOREFProspectType=N'',@sVAddress1=N'',@sVAddress2=N'',@sVAddress3=N'',@sVTown=N'',@sVCounty=N'',@TOREFVCountry=N'',@sVPostcode=N'',@bHasSepticUnit=0,@lBusinessManagerTempID=0,@lProspectTypeID=1,@lGroupID=1,@lCountryID=180,@lVCountryID=-2,@bDeleted=0,@lValueID=NULL,@sGeneralEmail=N'',@lMarketingID=48509669,@sVisitingAddress=N'',@bIsolator=0,@bLAF=0,@bGradeAB=0,@bGradeCD=0,@bUnclassified=0,@bNoProduction=0,@sIsolatorQty=N'',@sLAFQty=N'',@sGradeABArea=N'',@sGradeCDArea=N'',@sUnclassifiedArea=N'',@bIncludeInKAM=1,@fLat=55.378050999999999,@fLong=-3.4359730000000002,@bRespQuality=0,@bRespMicro=0,@bRespPurchasing=0,@bRespValidation=0,@bKindIsolator=0,@bKindRABS=0,@bKindOLA=0,@bKindOLB=0,@bKindOLC=0,@bKindOLD=0,@lNoCleanroomOperatives=0,@sProductsManufactured=N'',@sComments=N'Test wm4',@lValueAlcohol=0,@lValueBiocides=0,@lValueWipes=0,@lValueEquipment=0,@lValueNonSterile=0,@lValueOther=0,@lGeocodeAttempts=6,@sGeocodeLastStatus=N'OK'
select @p1

屏幕截图的前两行来自网络应用程序(不起作用),最后两行来自SSMS(工作正常)

但是如果我们从上面复制确切的SQL并在SSMS中运行它(使用与Web应用程序相同的登录名),它可以正常插入或更新记录并成功从中检索lat / lng网络服务

代码:

Institution.Save()

Public Function Save() As Integer

    Dim cn As New SqlConnection(My.Settings.ShieldCRMConnectionString)
    Dim cmd As New SqlCommand
    Dim strSQL As String = "usp_web_InsertUpdateInstitution"

    Try
    cn.Open()
    cmd.Connection = cn
    cmd.CommandText = strSQL
    cmd.CommandType = CommandType.StoredProcedure

    Dim prmInstitutionID As New SqlParameter
    prmInstitutionID.ParameterName = "@lInstitutionID"
    prmInstitutionID.Value = intInstitutionID
    prmInstitutionID.Direction = ParameterDirection.InputOutput
    cmd.Parameters.Add(prmInstitutionID)

    '** Parameters clipped out for readability

    cmd.ExecuteNonQuery()

    Return cmd.Parameters("@lInstitutionID").Value

Catch ex As Exception
    Elmah.ErrorSignal.FromCurrentContext.Raise(ex)
    Return -1
Finally
    cmd.Dispose()
    cn.Close()
    cn.Dispose()
End Try

trg_Geolocation

ALTER TRIGGER [dbo].[trg_Geolocation] ON [dbo].[tblInstitution] AFTER INSERT, UPDATE
AS
BEGIN

    DECLARE @lInstitutionID INT
    DECLARE @sAddress1 VARCHAR(500)
    DECLARE @sAddress2 VARCHAR(500)
    DECLARE @sAddress3 VARCHAR(500)
    DECLARE @sTown VARCHAR(500)
    DECLARE @sCounty VARCHAR(500)
    DECLARE @sPostcode VARCHAR(500)
    DECLARE @sCountry VARCHAR(500)
    DECLARE @lCountryID INT

    DECLARE cur CURSOR FOR

    SELECT lInstitutionID,
           sAddress1,
           sAddress2,
           sAddress3,
           sTown,
           sCounty,
           sPostCode,
           C.lCountryID,
           C.sName AS sCountry
    FROM inserted I
    INNER JOIN refCountry C ON I.lCountryID = C.lCountryID
    WHERE ISNULL(bIncludeInKAM, 0) = 1

    OPEN cur

    FETCH NEXT FROM cur INTO @lInstitutionID, @sAddress1, @sAddress2, @sAddress3, @sTown, @sCounty, @sPostCode, @lCountryID, @sCountry

    WHILE @@FETCH_STATUS = 0
    BEGIN

        DECLARE @fLat FLOAT
        DECLARE @fLng FLOAT
        DECLARE @sAddress VARCHAR(MAX)
        DECLARE @sLastStatus VARCHAR(200)

        SELECT @fLat = NULL, @fLng = NULL, @sAddress = NULL

        SELECT @sAddress =
        CASE WHEN REPLACE(REPLACE(ISNULL(@sAddress1 + ', ', '') + ISNULL(@sAddress2 + ', ', '') + ISNULL(@sAddress3 + ', ', '') + ISNULL(@sTown + ', ', '') + ISNULL(@sCounty + ', ', '') + @sCountry, ', , , ', ', '), ', , ', ', ')
        LIKE ', %' THEN RIGHT(REPLACE(REPLACE(ISNULL(@sAddress1 + ', ', '') + ISNULL(@sAddress2 + ', ', '') + ISNULL(@sAddress3 + ', ', '') + ISNULL(@sTown + ', ', '') + ISNULL(@sCounty + ', ', '') + @sCountry, ', , , ', ', '), ', , ', ', '),
        LEN(REPLACE(REPLACE(ISNULL(@sAddress1 + ', ', '') + ISNULL(@sAddress2 + ', ', '') + ISNULL(@sAddress3 + ', ', '') + ISNULL(@sTown + ', ', '') + ISNULL(@sCounty + ', ', '') + @sCountry, ', , , ', ', '), ', , ', ', ')) - 2)
        ELSE REPLACE(REPLACE(ISNULL(@sAddress1 + ', ', '') + ISNULL(@sAddress2 + ', ', '') + ISNULL(@sAddress3 + ', ', '') + ISNULL(@sTown + ', ', '') + ISNULL(@sCounty + ', ', '') + @sCountry, ', , , ', ', '), ', , ', ', ') END

        BEGIN TRY
            EXEC usp_web_kam_Geocode @sAddress = @sAddress OUTPUT, @fLat = @fLat OUTPUT, @fLng = @fLng OUTPUT, @sGeocodeLastStatus = @sLastStatus OUTPUT
        END TRY
        BEGIN CATCH
            SELECT ERROR_MESSAGE()
        END CATCH    

        IF NOT (@fLat IS NULL AND @fLng IS NULL)
        BEGIN

            UPDATE tblInstitution
            SET fLat = @fLat,
               fLong = @fLng,
               lGeocodeAttempts = ISNULL(lGeocodeAttempts, 0) + 1,
               sGeocodeLastStatus = @sLastStatus
            WHERE lInstitutionID = @lInstitutionID

        END

        FETCH NEXT FROM cur INTO @lInstitutionID, @sAddress1, @sAddress2, @sAddress3, @sTown, @sCounty, @sPostCode, @lCountryID, @sCountry

    END

    CLOSE cur
    DEALLOCATE cur

END

usp_web_kam_Geocode

ALTER PROCEDURE [dbo].[usp_web_kam_Geocode]

    @sAddress VARCHAR(80) = NULL OUTPUT,

    @sCity VARCHAR(40) = NULL OUTPUT,
    @sState VARCHAR(40) = NULL OUTPUT,
    @sCounty VARCHAR(40) = NULL OUTPUT,
    @sCountry VARCHAR(40) = NULL OUTPUT,
    @sPostCode VARCHAR(20) = NULL OUTPUT,

    @sGeocodeLastStatus VARCHAR(200) = NULL OUTPUT,
    @fLat FLOAT = NULL OUTPUT,
    @fLng FLOAT = NULL OUTPUT,
    @sMapURL VARCHAR(1024) = NULL OUTPUT

AS

BEGIN

    SET NOCOUNT ON

    DECLARE @sURL varchar(MAX)
    SET @sURL = 'http://maps.google.com/maps/api/geocode/xml?sensor=false&address=' +
    CASE WHEN @sAddress IS NOT NULL THEN @sAddress ELSE '' END +
    CASE WHEN @sCity IS NOT NULL THEN ', ' + @sCity ELSE '' END +
    CASE WHEN @sState IS NOT NULL THEN ', ' + @sState ELSE '' END +
    CASE WHEN @sPostCode IS NOT NULL THEN ', ' + @sPostCode ELSE '' END +
    CASE WHEN @sCountry IS NOT NULL THEN ', ' + @sCountry ELSE '' END
    SET @sURL = REPLACE(@sURL, ' ', '+')

    DECLARE @Response varchar(8000)
    DECLARE @XML xml
    DECLARE @Obj int 
    DECLARE @Result int 
    DECLARE @HTTPStatus int 
    DECLARE @ErrorMsg varchar(MAX)

    EXEC @Result = sp_OACreate 'MSXML2.ServerXMLHttp', @Obj OUT 

    BEGIN TRY
    EXEC @Result = sp_OAMethod @Obj, 'open', NULL, 'GET', @sURL, false
    EXEC @Result = sp_OAMethod @Obj, 'setRequestHeader', NULL, 'Content-Type', 'application/x-www-form-urlencoded'
    EXEC @Result = sp_OAMethod @Obj, send, NULL, ''

    EXEC @Result = sp_OAGetProperty @Obj, 'status', @HTTPStatus OUT 
    EXEC @Result = sp_OAGetProperty @Obj, 'responseXML.xml', @Response OUT 
    END TRY
    BEGIN CATCH
    SET @ErrorMsg = ERROR_MESSAGE()
    END CATCH

    EXEC @Result = sp_OADestroy @Obj

    IF (@ErrorMsg IS NOT NULL) OR (@HTTPStatus <> 200) BEGIN
    SET @ErrorMsg = 'Error in Geocode: ' + ISNULL(@ErrorMsg, 'HTTP result is: ' + CAST(@HTTPStatus AS varchar(10)))
    RAISERROR(@ErrorMsg, 16, 1, @HTTPStatus)
    RETURN 
    END

    SET @XML = CAST(@Response AS XML)

    SET @sGeocodeLastStatus = @XML.value('(/GeocodeResponse/status) [1]', 'varchar(200)') 
    SET @fLat = @XML.value('(/GeocodeResponse/result/geometry/location/lat) [1]', 'numeric(9,6)')
    SET @fLng = @XML.value('(/GeocodeResponse/result/geometry/location/lng) [1]', 'numeric(9,6)')

    SET @sCity = @XML.value('(/GeocodeResponse/result/address_component[type="locality"]/long_name) [1]', 'varchar(40)') 
    SET @sState = @XML.value('(/GeocodeResponse/result/address_component[type="administrative_area_level_1"]/short_name) [1]', 'varchar(40)') 
    SET @sPostCode = @XML.value('(/GeocodeResponse/result/address_component[type="postal_code"]/long_name) [1]', 'varchar(20)') 
    SET @sCountry = @XML.value('(/GeocodeResponse/result/address_component[type="country"]/short_name) [1]', 'varchar(40)') 
    SET @sCounty = @XML.value('(/GeocodeResponse/result/address_component[type="administrative_area_level_2"]/short_name) [1]', 'varchar(40)') 

    SET @sAddress = 
    ISNULL(@XML.value('(/GeocodeResponse/result/address_component[type="street_number"]/long_name) [1]', 'varchar(40)'), '???') + ' ' +
    ISNULL(@XML.value('(/GeocodeResponse/result/address_component[type="route"]/long_name) [1]', 'varchar(40)'), '???') 
    SET @sMapURL = 'http://maps.google.com/maps?f=q&hl=en&q=' + CAST(@fLat AS varchar(20)) + '+' + CAST(@fLng AS varchar(20))

END

0 个答案:

没有答案