Difficult VB/MTS/SQL Error 
Author Message
 Difficult VB/MTS/SQL Error

Sorry for cross-posting, but I this applies to VB, MTS, and SQL Server.

I have a VB6 EXE that calls a VB6 ActiveX DLL that is registered in MTS (and
is set as "requires transaction"). The DLL has a method (code listed below)
that starts a transaction, loops through an array of strings using an ADO
Command object to insert each string into a table in the database, and ends
the transaction. If a duplicate string is encountered, the database rejects
the string, an error is raised, and the method continues with the next
string in the array using a "Resume Next" statement.

My test data includes an array of about 1200 strings, and everything works
great, EXCEPT when I try to insert the same array more than once (which will
result in every string being a duplicate). As expected, each row is rejected
(SQL Server error code=2627), and the method completes successfully (even
though no rows are successfully inserted--this is a perfectly OK scenario).
However, after the transaction is completed, an error is received by the EXE
from the method call, the database log files fill up and the SQL Server must
be restated. FYI, when I debug the whole thing, there are no errors anywhere
in the method--everything goes OK. But upon returning from the method call,
the generic "Method ~ of object ~ failed." error message is received.

I am not sure what's happening here. It seems that the insert is freaking
out the application and the database when the insert results in many
duplicates (maybe some kind of error overhead). My next course of action is
to remove the component from MTS, followed by reducing the number of lines
in the test data.

Thanks in advance!

Jamie Schatte
Millennia Systems

www.millenniasystems.com

****************************************

Public Sub DSMMeterReadCSVFile(ByVal ConnectionString As String, _
                                ByRef CSVLines() As String)

' --------------------------------------------------------------------------
-
    ' This prcedure processes an entire CSV file as an array of file lines.

' --------------------------------------------------------------------------
-

    On Error GoTo HandleError

    Dim adoConnection               As ADODB.Connection
    Dim adoCmdRegisterDataAdd       As ADODB.Command
    Dim dsadoRegisterDataRec        As DSADO.RegisterDataRec
    Dim mtsContext                  As ObjectContext
    Dim AlarmCount                  As Integer
    Dim Alarms                      As String
    Dim Alarm                       As String
    Dim CSVLine                     As String
    Dim I                           As Integer

    ' Continue the current transaction
    Set mtsContext = GetObjectContext

    ' Setup the database connection
    Set adoConnection = New ADODB.Connection
    adoConnection.Open ConnectionString

    ' Setup the command to add records to the REGISTER_DATA table
    Set adoCmdRegisterDataAdd = New ADODB.Command
    With adoCmdRegisterDataAdd
        Set .ActiveConnection = adoConnection
        .CommandType = adCmdText
        .CommandText = " INSERT INTO dbo.REGISTER_DATA              " & _
                       "       (MeterID,                            " & _
                       "        ChannelID,                          " & _
                       "        TimeStamp,                          " & _
                       "        RegisterValue,                      " & _
                       "        ReadSource,                         " & _
                       "        ReadType,                           " & _
                       "        AlarmFlag)                          " & _
                       "VALUES (?,                                  " & _
                       "        ?,                                  " & _
                       "        ?,                                  " & _
                       "        ?,                                  " & _
                       "        ?,                                  " & _
                       "        ?,                                  " & _
                       "        ?)                                  "
        .CreateParameter , adInteger
        .CreateParameter , adInteger
        .CreateParameter , adChar, , 30
        .CreateParameter , adDouble
        .CreateParameter , adChar, , 1
        .CreateParameter , adChar, , 1
        .CreateParameter , adChar, , 1
    End With

    ' Parse the file lines
    For I = LBound(CSVLines) To UBound(CSVLines)

        ' Get the next line in the file
        CSVLine = CSVLines(I)

        ' Process the meter reading information for the meter
        With dsadoRegisterDataRec

            ' Format the meter reading data structure
            .MeterID = Val(DSCParseLine(CSVLine, 1))
            .ChannelID = Val(DSCParseLine(CSVLine, 2))
            .TimeStamp = DSCFormatTimeStamp(DSCParseLine(CSVLine, 3))
            .ReadSource = DSCParseLine(CSVLine, 4)
            .RegisterValue = Val(DSCParseLine(CSVLine, 5))
            .ReadType = ""
            Alarms = DSCParseLine(CSVLine, 6)
            If Len(Alarms) = 0 Then
                .AlarmFlag = "N"
            Else
                .AlarmFlag = "Y"
            End If

            ' Add the meter reading to the REGISTER_DATA table
            adoCmdRegisterDataAdd.Parameters(0).Value = .MeterID
            adoCmdRegisterDataAdd.Parameters(1).Value = .ChannelID
            adoCmdRegisterDataAdd.Parameters(2).Value = .TimeStamp
            adoCmdRegisterDataAdd.Parameters(3).Value = .RegisterValue
            adoCmdRegisterDataAdd.Parameters(4).Value = .ReadSource
            adoCmdRegisterDataAdd.Parameters(5).Value = .ReadType
            adoCmdRegisterDataAdd.Parameters(6).Value = .AlarmFlag
            adoCmdRegisterDataAdd.Execute

        End With

    Next I

    ' Free any objects that were allocated during the function
    If adoConnection.State <> adStateClosed Then adoConnection.Close
    If Not adoConnection Is Nothing Then Set adoConnection = Nothing
    If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd =
Nothing

    ' Continue the current the transaction
    mtsContext.SetComplete
    If Not mtsContext Is Nothing Then Set mtsContext = Nothing

    Exit Sub

HandleError:
    ' Continue if the error is a duplicate row
    If adoConnection.Errors.Count > 0 Then
        If adoConnection.Errors(0).NativeError = 2627 Then Resume Next
    End If

    ' Free any objects that were allocated during the function
    If adoConnection.State <> adStateClosed Then adoConnection.Close
    If Not adoConnection Is Nothing Then Set adoConnection = Nothing
    If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd =
Nothing

    ' Abort the transaction and raise the error to the client
    mtsContext.SetAbort
    If Not mtsContext Is Nothing Then Set mtsContext = Nothing

    ' Raise the error to the client
    Err.Raise Err.Number, STR_CLASSNAME & Err.Source, Err.Description

End Sub



Sat, 17 Nov 2001 03:00:00 GMT  
 Difficult VB/MTS/SQL Error


Fri, 19 Jun 1992 00:00:00 GMT  
 Difficult VB/MTS/SQL Error
When I remove the component from Transaction Server, everything works fine.
I can insert the array of strings many times, and each time after the first,
the records are rejected and everything works great.

Now, why is this so? This component REALLY needs to be in MTS. Is there some
sort of overhead that MTS is incurring each time I insert a duplicate row
and keep going? Do I need to break the transaction into smaller pieces--like
after every 100 rows? If so, why do the duplicate rows cause this when good
ones do not?

Thanks again!

Jamie Schatte
Millennia Systems

www.millenniasystems.com



Sat, 17 Nov 2001 03:00:00 GMT  
 Difficult VB/MTS/SQL Error


Fri, 19 Jun 1992 00:00:00 GMT  
 Difficult VB/MTS/SQL Error
This was happening to me when I was calling a method of component that
belonged to a transaction and where another component had previously called
the SetAbort method. To solve this problem I had to put a Err.Raise method
after calling SetAbort on every components.

--

Microsoft Certified Professional
Significado do Seu Nome: http://www.c-avolio.com/nomes

Quote:
> Sorry for cross-posting, but I this applies to VB, MTS, and SQL Server.

> I have a VB6 EXE that calls a VB6 ActiveX DLL that is registered in MTS
(and
> is set as "requires transaction"). The DLL has a method (code listed
below)
> that starts a transaction, loops through an array of strings using an ADO
> Command object to insert each string into a table in the database, and
ends
> the transaction. If a duplicate string is encountered, the database
rejects
> the string, an error is raised, and the method continues with the next
> string in the array using a "Resume Next" statement.

> My test data includes an array of about 1200 strings, and everything works
> great, EXCEPT when I try to insert the same array more than once (which
will
> result in every string being a duplicate). As expected, each row is
rejected
> (SQL Server error code=2627), and the method completes successfully (even
> though no rows are successfully inserted--this is a perfectly OK
scenario).
> However, after the transaction is completed, an error is received by the
EXE
> from the method call, the database log files fill up and the SQL Server
must
> be restated. FYI, when I debug the whole thing, there are no errors
anywhere
> in the method--everything goes OK. But upon returning from the method
call,
> the generic "Method ~ of object ~ failed." error message is received.

> I am not sure what's happening here. It seems that the insert is freaking
> out the application and the database when the insert results in many
> duplicates (maybe some kind of error overhead). My next course of action
is
> to remove the component from MTS, followed by reducing the number of lines
> in the test data.

> Thanks in advance!

> Jamie Schatte
> Millennia Systems

> www.millenniasystems.com

> ****************************************

> Public Sub DSMMeterReadCSVFile(ByVal ConnectionString As String, _
>                                 ByRef CSVLines() As String)

' --------------------------------------------------------------------------
Quote:
> -
>     ' This prcedure processes an entire CSV file as an array of file
lines.

' --------------------------------------------------------------------------

- Show quoted text -

Quote:
> -

>     On Error GoTo HandleError

>     Dim adoConnection               As ADODB.Connection
>     Dim adoCmdRegisterDataAdd       As ADODB.Command
>     Dim dsadoRegisterDataRec        As DSADO.RegisterDataRec
>     Dim mtsContext                  As ObjectContext
>     Dim AlarmCount                  As Integer
>     Dim Alarms                      As String
>     Dim Alarm                       As String
>     Dim CSVLine                     As String
>     Dim I                           As Integer

>     ' Continue the current transaction
>     Set mtsContext = GetObjectContext

>     ' Setup the database connection
>     Set adoConnection = New ADODB.Connection
>     adoConnection.Open ConnectionString

>     ' Setup the command to add records to the REGISTER_DATA table
>     Set adoCmdRegisterDataAdd = New ADODB.Command
>     With adoCmdRegisterDataAdd
>         Set .ActiveConnection = adoConnection
>         .CommandType = adCmdText
>         .CommandText = " INSERT INTO dbo.REGISTER_DATA              " & _
>                        "       (MeterID,                            " & _
>                        "        ChannelID,                          " & _
>                        "        TimeStamp,                          " & _
>                        "        RegisterValue,                      " & _
>                        "        ReadSource,                         " & _
>                        "        ReadType,                           " & _
>                        "        AlarmFlag)                          " & _
>                        "VALUES (?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?)                                  "
>         .CreateParameter , adInteger
>         .CreateParameter , adInteger
>         .CreateParameter , adChar, , 30
>         .CreateParameter , adDouble
>         .CreateParameter , adChar, , 1
>         .CreateParameter , adChar, , 1
>         .CreateParameter , adChar, , 1
>     End With

>     ' Parse the file lines
>     For I = LBound(CSVLines) To UBound(CSVLines)

>         ' Get the next line in the file
>         CSVLine = CSVLines(I)

>         ' Process the meter reading information for the meter
>         With dsadoRegisterDataRec

>             ' Format the meter reading data structure
>             .MeterID = Val(DSCParseLine(CSVLine, 1))
>             .ChannelID = Val(DSCParseLine(CSVLine, 2))
>             .TimeStamp = DSCFormatTimeStamp(DSCParseLine(CSVLine, 3))
>             .ReadSource = DSCParseLine(CSVLine, 4)
>             .RegisterValue = Val(DSCParseLine(CSVLine, 5))
>             .ReadType = ""
>             Alarms = DSCParseLine(CSVLine, 6)
>             If Len(Alarms) = 0 Then
>                 .AlarmFlag = "N"
>             Else
>                 .AlarmFlag = "Y"
>             End If

>             ' Add the meter reading to the REGISTER_DATA table
>             adoCmdRegisterDataAdd.Parameters(0).Value = .MeterID
>             adoCmdRegisterDataAdd.Parameters(1).Value = .ChannelID
>             adoCmdRegisterDataAdd.Parameters(2).Value = .TimeStamp
>             adoCmdRegisterDataAdd.Parameters(3).Value = .RegisterValue
>             adoCmdRegisterDataAdd.Parameters(4).Value = .ReadSource
>             adoCmdRegisterDataAdd.Parameters(5).Value = .ReadType
>             adoCmdRegisterDataAdd.Parameters(6).Value = .AlarmFlag
>             adoCmdRegisterDataAdd.Execute

>         End With

>     Next I

>     ' Free any objects that were allocated during the function
>     If adoConnection.State <> adStateClosed Then adoConnection.Close
>     If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>     If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd
=
> Nothing

>     ' Continue the current the transaction
>     mtsContext.SetComplete
>     If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>     Exit Sub

> HandleError:
>     ' Continue if the error is a duplicate row
>     If adoConnection.Errors.Count > 0 Then
>         If adoConnection.Errors(0).NativeError = 2627 Then Resume Next
>     End If

>     ' Free any objects that were allocated during the function
>     If adoConnection.State <> adStateClosed Then adoConnection.Close
>     If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>     If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd
=
> Nothing

>     ' Abort the transaction and raise the error to the client
>     mtsContext.SetAbort
>     If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>     ' Raise the error to the client
>     Err.Raise Err.Number, STR_CLASSNAME & Err.Source, Err.Description

> End Sub



Sat, 17 Nov 2001 03:00:00 GMT  
 Difficult VB/MTS/SQL Error
one point & one question

1) i always raise the error on entry to the error handler, followed by
releasing resources then set abort.  i have never experienced the "Method ~
of object ~ failed." may be just luck or ....
2) have you considered using a straight connection/execute/insert?

Quote:

>Sorry for cross-posting, but I this applies to VB, MTS, and SQL Server.

>I have a VB6 EXE that calls a VB6 ActiveX DLL that is registered in MTS
(and
>is set as "requires transaction"). The DLL has a method (code listed below)
>that starts a transaction, loops through an array of strings using an ADO
>Command object to insert each string into a table in the database, and ends
>the transaction. If a duplicate string is encountered, the database rejects
>the string, an error is raised, and the method continues with the next
>string in the array using a "Resume Next" statement.

>My test data includes an array of about 1200 strings, and everything works
>great, EXCEPT when I try to insert the same array more than once (which
will
>result in every string being a duplicate). As expected, each row is
rejected
>(SQL Server error code=2627), and the method completes successfully (even
>though no rows are successfully inserted--this is a perfectly OK scenario).
>However, after the transaction is completed, an error is received by the
EXE
>from the method call, the database log files fill up and the SQL Server
must
>be restated. FYI, when I debug the whole thing, there are no errors
anywhere
>in the method--everything goes OK. But upon returning from the method call,
>the generic "Method ~ of object ~ failed." error message is received.

>I am not sure what's happening here. It seems that the insert is freaking
>out the application and the database when the insert results in many
>duplicates (maybe some kind of error overhead). My next course of action is
>to remove the component from MTS, followed by reducing the number of lines
>in the test data.

>Thanks in advance!

>Jamie Schatte
>Millennia Systems

>www.millenniasystems.com

>****************************************

>Public Sub DSMMeterReadCSVFile(ByVal ConnectionString As String, _
>                                ByRef CSVLines() As String)

>' -------------------------------------------------------------------------
-
>-
>    ' This prcedure processes an entire CSV file as an array of file lines.

>' -------------------------------------------------------------------------
-
>-

>    On Error GoTo HandleError

>    Dim adoConnection               As ADODB.Connection
>    Dim adoCmdRegisterDataAdd       As ADODB.Command
>    Dim dsadoRegisterDataRec        As DSADO.RegisterDataRec
>    Dim mtsContext                  As ObjectContext
>    Dim AlarmCount                  As Integer
>    Dim Alarms                      As String
>    Dim Alarm                       As String
>    Dim CSVLine                     As String
>    Dim I                           As Integer

>    ' Continue the current transaction
>    Set mtsContext = GetObjectContext

>    ' Setup the database connection
>    Set adoConnection = New ADODB.Connection
>    adoConnection.Open ConnectionString

>    ' Setup the command to add records to the REGISTER_DATA table
>    Set adoCmdRegisterDataAdd = New ADODB.Command
>    With adoCmdRegisterDataAdd
>        Set .ActiveConnection = adoConnection
>        .CommandType = adCmdText
>        .CommandText = " INSERT INTO dbo.REGISTER_DATA              " & _
>                       "       (MeterID,                            " & _
>                       "        ChannelID,                          " & _
>                       "        TimeStamp,                          " & _
>                       "        RegisterValue,                      " & _
>                       "        ReadSource,                         " & _
>                       "        ReadType,                           " & _
>                       "        AlarmFlag)                          " & _
>                       "VALUES (?,                                  " & _
>                       "        ?,                                  " & _
>                       "        ?,                                  " & _
>                       "        ?,                                  " & _
>                       "        ?,                                  " & _
>                       "        ?,                                  " & _
>                       "        ?)                                  "
>        .CreateParameter , adInteger
>        .CreateParameter , adInteger
>        .CreateParameter , adChar, , 30
>        .CreateParameter , adDouble
>        .CreateParameter , adChar, , 1
>        .CreateParameter , adChar, , 1
>        .CreateParameter , adChar, , 1
>    End With

>    ' Parse the file lines
>    For I = LBound(CSVLines) To UBound(CSVLines)

>        ' Get the next line in the file
>        CSVLine = CSVLines(I)

>        ' Process the meter reading information for the meter
>        With dsadoRegisterDataRec

>            ' Format the meter reading data structure
>            .MeterID = Val(DSCParseLine(CSVLine, 1))
>            .ChannelID = Val(DSCParseLine(CSVLine, 2))
>            .TimeStamp = DSCFormatTimeStamp(DSCParseLine(CSVLine, 3))
>            .ReadSource = DSCParseLine(CSVLine, 4)
>            .RegisterValue = Val(DSCParseLine(CSVLine, 5))
>            .ReadType = ""
>            Alarms = DSCParseLine(CSVLine, 6)
>            If Len(Alarms) = 0 Then
>                .AlarmFlag = "N"
>            Else
>                .AlarmFlag = "Y"
>            End If

>            ' Add the meter reading to the REGISTER_DATA table
>            adoCmdRegisterDataAdd.Parameters(0).Value = .MeterID
>            adoCmdRegisterDataAdd.Parameters(1).Value = .ChannelID
>            adoCmdRegisterDataAdd.Parameters(2).Value = .TimeStamp
>            adoCmdRegisterDataAdd.Parameters(3).Value = .RegisterValue
>            adoCmdRegisterDataAdd.Parameters(4).Value = .ReadSource
>            adoCmdRegisterDataAdd.Parameters(5).Value = .ReadType
>            adoCmdRegisterDataAdd.Parameters(6).Value = .AlarmFlag
>            adoCmdRegisterDataAdd.Execute

>        End With

>    Next I

>    ' Free any objects that were allocated during the function
>    If adoConnection.State <> adStateClosed Then adoConnection.Close
>    If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>    If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd
=
>Nothing

>    ' Continue the current the transaction
>    mtsContext.SetComplete
>    If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>    Exit Sub

>HandleError:
>    ' Continue if the error is a duplicate row
>    If adoConnection.Errors.Count > 0 Then
>        If adoConnection.Errors(0).NativeError = 2627 Then Resume Next
>    End If

>    ' Free any objects that were allocated during the function
>    If adoConnection.State <> adStateClosed Then adoConnection.Close
>    If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>    If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd
=
>Nothing

>    ' Abort the transaction and raise the error to the client
>    mtsContext.SetAbort
>    If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>    ' Raise the error to the client
>    Err.Raise Err.Number, STR_CLASSNAME & Err.Source, Err.Description

>End Sub



Sat, 17 Nov 2001 03:00:00 GMT  
 Difficult VB/MTS/SQL Error
MTS is not my speciality but you are committing the first transaction in
your DLL before exiting? I think there's a limit on nested transactions in
ADO which might cause your problem.

Quote:

>This was happening to me when I was calling a method of component that
>belonged to a transaction and where another component had previously called
>the SetAbort method. To solve this problem I had to put a Err.Raise method
>after calling SetAbort on every components.

>--

>Microsoft Certified Professional
>Significado do Seu Nome: http://www.c-avolio.com/nomes


>> Sorry for cross-posting, but I this applies to VB, MTS, and SQL Server.

>> I have a VB6 EXE that calls a VB6 ActiveX DLL that is registered in MTS
>(and
>> is set as "requires transaction"). The DLL has a method (code listed
>below)
>> that starts a transaction, loops through an array of strings using an ADO
>> Command object to insert each string into a table in the database, and
>ends
>> the transaction. If a duplicate string is encountered, the database
>rejects
>> the string, an error is raised, and the method continues with the next
>> string in the array using a "Resume Next" statement.

>> My test data includes an array of about 1200 strings, and everything
works
>> great, EXCEPT when I try to insert the same array more than once (which
>will
>> result in every string being a duplicate). As expected, each row is
>rejected
>> (SQL Server error code=2627), and the method completes successfully (even
>> though no rows are successfully inserted--this is a perfectly OK
>scenario).
>> However, after the transaction is completed, an error is received by the
>EXE
>> from the method call, the database log files fill up and the SQL Server
>must
>> be restated. FYI, when I debug the whole thing, there are no errors
>anywhere
>> in the method--everything goes OK. But upon returning from the method
>call,
>> the generic "Method ~ of object ~ failed." error message is received.

>> I am not sure what's happening here. It seems that the insert is freaking
>> out the application and the database when the insert results in many
>> duplicates (maybe some kind of error overhead). My next course of action
>is
>> to remove the component from MTS, followed by reducing the number of
lines
>> in the test data.

>> Thanks in advance!

>> Jamie Schatte
>> Millennia Systems

>> www.millenniasystems.com

>> ****************************************

>> Public Sub DSMMeterReadCSVFile(ByVal ConnectionString As String, _
>>                                 ByRef CSVLines() As String)

>' -------------------------------------------------------------------------
-
>> -
>>     ' This prcedure processes an entire CSV file as an array of file
>lines.

>' -------------------------------------------------------------------------
-
>> -

>>     On Error GoTo HandleError

>>     Dim adoConnection               As ADODB.Connection
>>     Dim adoCmdRegisterDataAdd       As ADODB.Command
>>     Dim dsadoRegisterDataRec        As DSADO.RegisterDataRec
>>     Dim mtsContext                  As ObjectContext
>>     Dim AlarmCount                  As Integer
>>     Dim Alarms                      As String
>>     Dim Alarm                       As String
>>     Dim CSVLine                     As String
>>     Dim I                           As Integer

>>     ' Continue the current transaction
>>     Set mtsContext = GetObjectContext

>>     ' Setup the database connection
>>     Set adoConnection = New ADODB.Connection
>>     adoConnection.Open ConnectionString

>>     ' Setup the command to add records to the REGISTER_DATA table
>>     Set adoCmdRegisterDataAdd = New ADODB.Command
>>     With adoCmdRegisterDataAdd
>>         Set .ActiveConnection = adoConnection
>>         .CommandType = adCmdText
>>         .CommandText = " INSERT INTO dbo.REGISTER_DATA              " & _
>>                        "       (MeterID,                            " & _
>>                        "        ChannelID,                          " & _
>>                        "        TimeStamp,                          " & _
>>                        "        RegisterValue,                      " & _
>>                        "        ReadSource,                         " & _
>>                        "        ReadType,                           " & _
>>                        "        AlarmFlag)                          " & _
>>                        "VALUES (?,                                  " & _
>>                        "        ?,                                  " & _
>>                        "        ?,                                  " & _
>>                        "        ?,                                  " & _
>>                        "        ?,                                  " & _
>>                        "        ?,                                  " & _
>>                        "        ?)                                  "
>>         .CreateParameter , adInteger
>>         .CreateParameter , adInteger
>>         .CreateParameter , adChar, , 30
>>         .CreateParameter , adDouble
>>         .CreateParameter , adChar, , 1
>>         .CreateParameter , adChar, , 1
>>         .CreateParameter , adChar, , 1
>>     End With

>>     ' Parse the file lines
>>     For I = LBound(CSVLines) To UBound(CSVLines)

>>         ' Get the next line in the file
>>         CSVLine = CSVLines(I)

>>         ' Process the meter reading information for the meter
>>         With dsadoRegisterDataRec

>>             ' Format the meter reading data structure
>>             .MeterID = Val(DSCParseLine(CSVLine, 1))
>>             .ChannelID = Val(DSCParseLine(CSVLine, 2))
>>             .TimeStamp = DSCFormatTimeStamp(DSCParseLine(CSVLine, 3))
>>             .ReadSource = DSCParseLine(CSVLine, 4)
>>             .RegisterValue = Val(DSCParseLine(CSVLine, 5))
>>             .ReadType = ""
>>             Alarms = DSCParseLine(CSVLine, 6)
>>             If Len(Alarms) = 0 Then
>>                 .AlarmFlag = "N"
>>             Else
>>                 .AlarmFlag = "Y"
>>             End If

>>             ' Add the meter reading to the REGISTER_DATA table
>>             adoCmdRegisterDataAdd.Parameters(0).Value = .MeterID
>>             adoCmdRegisterDataAdd.Parameters(1).Value = .ChannelID
>>             adoCmdRegisterDataAdd.Parameters(2).Value = .TimeStamp
>>             adoCmdRegisterDataAdd.Parameters(3).Value = .RegisterValue
>>             adoCmdRegisterDataAdd.Parameters(4).Value = .ReadSource
>>             adoCmdRegisterDataAdd.Parameters(5).Value = .ReadType
>>             adoCmdRegisterDataAdd.Parameters(6).Value = .AlarmFlag
>>             adoCmdRegisterDataAdd.Execute

>>         End With

>>     Next I

>>     ' Free any objects that were allocated during the function
>>     If adoConnection.State <> adStateClosed Then adoConnection.Close
>>     If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>>     If Not adoCmdRegisterDataAdd Is Nothing Then Set

adoCmdRegisterDataAdd

- Show quoted text -

Quote:
>=
>> Nothing

>>     ' Continue the current the transaction
>>     mtsContext.SetComplete
>>     If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>>     Exit Sub

>> HandleError:
>>     ' Continue if the error is a duplicate row
>>     If adoConnection.Errors.Count > 0 Then
>>         If adoConnection.Errors(0).NativeError = 2627 Then Resume Next
>>     End If

>>     ' Free any objects that were allocated during the function
>>     If adoConnection.State <> adStateClosed Then adoConnection.Close
>>     If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>>     If Not adoCmdRegisterDataAdd Is Nothing Then Set

adoCmdRegisterDataAdd

- Show quoted text -

Quote:
>=
>> Nothing

>>     ' Abort the transaction and raise the error to the client
>>     mtsContext.SetAbort
>>     If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>>     ' Raise the error to the client
>>     Err.Raise Err.Number, STR_CLASSNAME & Err.Source, Err.Description

>> End Sub



Sun, 18 Nov 2001 03:00:00 GMT  
 Difficult VB/MTS/SQL Error
Jamie, your code looks fine, some things you might want to try in order to
narrow the problem are down are:

1.    Send the CSVLines as ByVal, I can't see where you're changing them, so
there shouldn't be any reason for you to have to retain a link to the
original array.
2.    I don't normally set the mtsobjectcontext variable to nothing after
performing an abort/complete, but I don't know if this affects anything.
3.    Reduce the time the component remains in memory to 1 minute, then wait
a few minutes before calling it again with the same array.  It could be
something to do with the fact it is still present in memory.  If this then
works, I don't know how you fix it, but at least you'll have narrowed it
down to the problem being caused by the DLL still residing in memory!  This
seems a likely suspect, as you say the program works when it is non-mts.
4.    Definitely ignore people saying you should raise the error first, as
soon as an error is raised the caller receives focus back.  You must perform
all setaborts and = nothing before raising the error.
5.    Try it without the WITH statement.  I use them myself, but I've heard
a few people discuss problems with them to do with memory leakage.  Can't
hurt to try it anyway!

As an additional point, as you are processing so many records, you may want
to consider creating a stored procedure instead of creating a manual insert
statement.  Stored procedures are pre-optimised and compiled, and tend to
run quite a bit quicker than running 'ad hoc' queries as you are doing.  For
inserts I've found it cuts the time down by about 25-30% (obviously this'll
be different for each application, so don't quote me!).  It depends whether
or not this is important to you, but you never know you may find as a fluke
that this also sorts out your problem!


Quote:
> Sorry for cross-posting, but I this applies to VB, MTS, and SQL Server.

> I have a VB6 EXE that calls a VB6 ActiveX DLL that is registered in MTS
(and
> is set as "requires transaction"). The DLL has a method (code listed
below)
> that starts a transaction, loops through an array of strings using an ADO
> Command object to insert each string into a table in the database, and
ends
> the transaction. If a duplicate string is encountered, the database
rejects
> the string, an error is raised, and the method continues with the next
> string in the array using a "Resume Next" statement.

> My test data includes an array of about 1200 strings, and everything works
> great, EXCEPT when I try to insert the same array more than once (which
will
> result in every string being a duplicate). As expected, each row is
rejected
> (SQL Server error code=2627), and the method completes successfully (even
> though no rows are successfully inserted--this is a perfectly OK
scenario).
> However, after the transaction is completed, an error is received by the
EXE
> from the method call, the database log files fill up and the SQL Server
must
> be restated. FYI, when I debug the whole thing, there are no errors
anywhere
> in the method--everything goes OK. But upon returning from the method
call,
> the generic "Method ~ of object ~ failed." error message is received.

> I am not sure what's happening here. It seems that the insert is freaking
> out the application and the database when the insert results in many
> duplicates (maybe some kind of error overhead). My next course of action
is
> to remove the component from MTS, followed by reducing the number of lines
> in the test data.

> Thanks in advance!

> Jamie Schatte
> Millennia Systems

> www.millenniasystems.com

> ****************************************

> Public Sub DSMMeterReadCSVFile(ByVal ConnectionString As String, _
>                                 ByRef CSVLines() As String)

' --------------------------------------------------------------------------
Quote:
> -
>     ' This prcedure processes an entire CSV file as an array of file
lines.

' --------------------------------------------------------------------------

- Show quoted text -

Quote:
> -

>     On Error GoTo HandleError

>     Dim adoConnection               As ADODB.Connection
>     Dim adoCmdRegisterDataAdd       As ADODB.Command
>     Dim dsadoRegisterDataRec        As DSADO.RegisterDataRec
>     Dim mtsContext                  As ObjectContext
>     Dim AlarmCount                  As Integer
>     Dim Alarms                      As String
>     Dim Alarm                       As String
>     Dim CSVLine                     As String
>     Dim I                           As Integer

>     ' Continue the current transaction
>     Set mtsContext = GetObjectContext

>     ' Setup the database connection
>     Set adoConnection = New ADODB.Connection
>     adoConnection.Open ConnectionString

>     ' Setup the command to add records to the REGISTER_DATA table
>     Set adoCmdRegisterDataAdd = New ADODB.Command
>     With adoCmdRegisterDataAdd
>         Set .ActiveConnection = adoConnection
>         .CommandType = adCmdText
>         .CommandText = " INSERT INTO dbo.REGISTER_DATA              " & _
>                        "       (MeterID,                            " & _
>                        "        ChannelID,                          " & _
>                        "        TimeStamp,                          " & _
>                        "        RegisterValue,                      " & _
>                        "        ReadSource,                         " & _
>                        "        ReadType,                           " & _
>                        "        AlarmFlag)                          " & _
>                        "VALUES (?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?)                                  "
>         .CreateParameter , adInteger
>         .CreateParameter , adInteger
>         .CreateParameter , adChar, , 30
>         .CreateParameter , adDouble
>         .CreateParameter , adChar, , 1
>         .CreateParameter , adChar, , 1
>         .CreateParameter , adChar, , 1
>     End With

>     ' Parse the file lines
>     For I = LBound(CSVLines) To UBound(CSVLines)

>         ' Get the next line in the file
>         CSVLine = CSVLines(I)

>         ' Process the meter reading information for the meter
>         With dsadoRegisterDataRec

>             ' Format the meter reading data structure
>             .MeterID = Val(DSCParseLine(CSVLine, 1))
>             .ChannelID = Val(DSCParseLine(CSVLine, 2))
>             .TimeStamp = DSCFormatTimeStamp(DSCParseLine(CSVLine, 3))
>             .ReadSource = DSCParseLine(CSVLine, 4)
>             .RegisterValue = Val(DSCParseLine(CSVLine, 5))
>             .ReadType = ""
>             Alarms = DSCParseLine(CSVLine, 6)
>             If Len(Alarms) = 0 Then
>                 .AlarmFlag = "N"
>             Else
>                 .AlarmFlag = "Y"
>             End If

>             ' Add the meter reading to the REGISTER_DATA table
>             adoCmdRegisterDataAdd.Parameters(0).Value = .MeterID
>             adoCmdRegisterDataAdd.Parameters(1).Value = .ChannelID
>             adoCmdRegisterDataAdd.Parameters(2).Value = .TimeStamp
>             adoCmdRegisterDataAdd.Parameters(3).Value = .RegisterValue
>             adoCmdRegisterDataAdd.Parameters(4).Value = .ReadSource
>             adoCmdRegisterDataAdd.Parameters(5).Value = .ReadType
>             adoCmdRegisterDataAdd.Parameters(6).Value = .AlarmFlag
>             adoCmdRegisterDataAdd.Execute

>         End With

>     Next I

>     ' Free any objects that were allocated during the function
>     If adoConnection.State <> adStateClosed Then adoConnection.Close
>     If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>     If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd
=
> Nothing

>     ' Continue the current the transaction
>     mtsContext.SetComplete
>     If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>     Exit Sub

> HandleError:
>     ' Continue if the error is a duplicate row
>     If adoConnection.Errors.Count > 0 Then
>         If adoConnection.Errors(0).NativeError = 2627 Then Resume Next
>     End If

>     ' Free any objects that were allocated during the function
>     If adoConnection.State <> adStateClosed Then adoConnection.Close
>     If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>     If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd
=
> Nothing

>     ' Abort the transaction and raise the error to the client
>     mtsContext.SetAbort
>     If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>     ' Raise the error to the client
>     Err.Raise Err.Number, STR_CLASSNAME & Err.Source, Err.Description

> End Sub



Sun, 18 Nov 2001 03:00:00 GMT  
 Difficult VB/MTS/SQL Error


Fri, 19 Jun 1992 00:00:00 GMT  
 Difficult VB/MTS/SQL Error
Thanks for the help, everyone! I moved the insert statements into stored
procedures, and this not only solved the problem but also made things run
MUCH quicker. The now code works great in MTS as either a server
(out-of-process) or a library (in-process) package.

Thanks again!

Jamie Schatte
Millennia Systems

www.millenniasystems.com



Sun, 18 Nov 2001 03:00:00 GMT  
 Difficult VB/MTS/SQL Error


Fri, 19 Jun 1992 00:00:00 GMT  
 Difficult VB/MTS/SQL Error
I Had the same problem, and i solved it by starting the MSDTC service on the
SQL Server box, i also upgrade to the SP3 for visual studio 6 and it gave me
more help on how to resolve this.

Ernesto Fernandez
C&A Mexico



Quote:
> Sorry for cross-posting, but I this applies to VB, MTS, and SQL Server.

> I have a VB6 EXE that calls a VB6 ActiveX DLL that is registered in MTS
(and
> is set as "requires transaction"). The DLL has a method (code listed
below)
> that starts a transaction, loops through an array of strings using an ADO
> Command object to insert each string into a table in the database, and
ends
> the transaction. If a duplicate string is encountered, the database
rejects
> the string, an error is raised, and the method continues with the next
> string in the array using a "Resume Next" statement.

> My test data includes an array of about 1200 strings, and everything works
> great, EXCEPT when I try to insert the same array more than once (which
will
> result in every string being a duplicate). As expected, each row is
rejected
> (SQL Server error code=2627), and the method completes successfully (even
> though no rows are successfully inserted--this is a perfectly OK
scenario).
> However, after the transaction is completed, an error is received by the
EXE
> from the method call, the database log files fill up and the SQL Server
must
> be restated. FYI, when I debug the whole thing, there are no errors
anywhere
> in the method--everything goes OK. But upon returning from the method
call,
> the generic "Method ~ of object ~ failed." error message is received.

> I am not sure what's happening here. It seems that the insert is freaking
> out the application and the database when the insert results in many
> duplicates (maybe some kind of error overhead). My next course of action
is
> to remove the component from MTS, followed by reducing the number of lines
> in the test data.

> Thanks in advance!

> Jamie Schatte
> Millennia Systems

> www.millenniasystems.com

> ****************************************

> Public Sub DSMMeterReadCSVFile(ByVal ConnectionString As String, _
>                                 ByRef CSVLines() As String)

' --------------------------------------------------------------------------
Quote:
> -
>     ' This prcedure processes an entire CSV file as an array of file
lines.

' --------------------------------------------------------------------------

- Show quoted text -

Quote:
> -

>     On Error GoTo HandleError

>     Dim adoConnection               As ADODB.Connection
>     Dim adoCmdRegisterDataAdd       As ADODB.Command
>     Dim dsadoRegisterDataRec        As DSADO.RegisterDataRec
>     Dim mtsContext                  As ObjectContext
>     Dim AlarmCount                  As Integer
>     Dim Alarms                      As String
>     Dim Alarm                       As String
>     Dim CSVLine                     As String
>     Dim I                           As Integer

>     ' Continue the current transaction
>     Set mtsContext = GetObjectContext

>     ' Setup the database connection
>     Set adoConnection = New ADODB.Connection
>     adoConnection.Open ConnectionString

>     ' Setup the command to add records to the REGISTER_DATA table
>     Set adoCmdRegisterDataAdd = New ADODB.Command
>     With adoCmdRegisterDataAdd
>         Set .ActiveConnection = adoConnection
>         .CommandType = adCmdText
>         .CommandText = " INSERT INTO dbo.REGISTER_DATA              " & _
>                        "       (MeterID,                            " & _
>                        "        ChannelID,                          " & _
>                        "        TimeStamp,                          " & _
>                        "        RegisterValue,                      " & _
>                        "        ReadSource,                         " & _
>                        "        ReadType,                           " & _
>                        "        AlarmFlag)                          " & _
>                        "VALUES (?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?,                                  " & _
>                        "        ?)                                  "
>         .CreateParameter , adInteger
>         .CreateParameter , adInteger
>         .CreateParameter , adChar, , 30
>         .CreateParameter , adDouble
>         .CreateParameter , adChar, , 1
>         .CreateParameter , adChar, , 1
>         .CreateParameter , adChar, , 1
>     End With

>     ' Parse the file lines
>     For I = LBound(CSVLines) To UBound(CSVLines)

>         ' Get the next line in the file
>         CSVLine = CSVLines(I)

>         ' Process the meter reading information for the meter
>         With dsadoRegisterDataRec

>             ' Format the meter reading data structure
>             .MeterID = Val(DSCParseLine(CSVLine, 1))
>             .ChannelID = Val(DSCParseLine(CSVLine, 2))
>             .TimeStamp = DSCFormatTimeStamp(DSCParseLine(CSVLine, 3))
>             .ReadSource = DSCParseLine(CSVLine, 4)
>             .RegisterValue = Val(DSCParseLine(CSVLine, 5))
>             .ReadType = ""
>             Alarms = DSCParseLine(CSVLine, 6)
>             If Len(Alarms) = 0 Then
>                 .AlarmFlag = "N"
>             Else
>                 .AlarmFlag = "Y"
>             End If

>             ' Add the meter reading to the REGISTER_DATA table
>             adoCmdRegisterDataAdd.Parameters(0).Value = .MeterID
>             adoCmdRegisterDataAdd.Parameters(1).Value = .ChannelID
>             adoCmdRegisterDataAdd.Parameters(2).Value = .TimeStamp
>             adoCmdRegisterDataAdd.Parameters(3).Value = .RegisterValue
>             adoCmdRegisterDataAdd.Parameters(4).Value = .ReadSource
>             adoCmdRegisterDataAdd.Parameters(5).Value = .ReadType
>             adoCmdRegisterDataAdd.Parameters(6).Value = .AlarmFlag
>             adoCmdRegisterDataAdd.Execute

>         End With

>     Next I

>     ' Free any objects that were allocated during the function
>     If adoConnection.State <> adStateClosed Then adoConnection.Close
>     If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>     If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd
=
> Nothing

>     ' Continue the current the transaction
>     mtsContext.SetComplete
>     If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>     Exit Sub

> HandleError:
>     ' Continue if the error is a duplicate row
>     If adoConnection.Errors.Count > 0 Then
>         If adoConnection.Errors(0).NativeError = 2627 Then Resume Next
>     End If

>     ' Free any objects that were allocated during the function
>     If adoConnection.State <> adStateClosed Then adoConnection.Close
>     If Not adoConnection Is Nothing Then Set adoConnection = Nothing
>     If Not adoCmdRegisterDataAdd Is Nothing Then Set adoCmdRegisterDataAdd
=
> Nothing

>     ' Abort the transaction and raise the error to the client
>     mtsContext.SetAbort
>     If Not mtsContext Is Nothing Then Set mtsContext = Nothing

>     ' Raise the error to the client
>     Err.Raise Err.Number, STR_CLASSNAME & Err.Source, Err.Description

> End Sub



Sat, 24 Nov 2001 03:00:00 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. Illegal operation error in SQL Server with VB component under MTS

2. Data not displayed using VB/MTS/SQL

3. VB SQL MTS

4. VB 6.0, MTS, and SQL 7.0 Book

5. MTS VB and clsutered SQL server 7.0

6. VB n-tier application using MTS in a SQL 7 CLuster - Failover -

7. VB SQL MTS

8. Difficult SQL Statement

9. Error 20639: SQL Expression error - Error in creating SQL Expression COM Parser (cpeaut32)

10. Trapping error number from MTS VB component

11. VB MTS Component error 429 and 0x80004015

12. Problem Raising Errors from VB Objects under MTS

 

 
Powered by phpBB® Forum Software