Say I have a function like this:
Private Function addNicheMerge(ByVal tyNicheMergePOLE As typeNicheMergePOLE) As Integer Implements IGenie.addNicheMerge
Dim objParameterValues As New clsParameterValues
Dim objCon As DbConnection
Dim paramValues() As DbParameter
Dim iConnectionBLL As DataAccessLayer.Connection.iConnectionBLL
iConnectionBLL = New clsConnectionBLL()
Dim intCount As Integer
Try
tyAcornCollision = New typeAcornCollision
objParameterValues = New clsParameterValues
objCon = iConnectionBLL.getDatabaseTypeByDescription("GENIE2")
Using objCon
Dim strSQL As String
strSQL = "If NOT Exists (SELECT * FROM dbNicheMergeLog WHERE MasterID=#MasterID AND ChildID = #ChildID) "
strSQL = strSQL & "INSERT INTO dbNicheMergeLog (MasterID, ChildID, DateAdded, GenieUpdated, done, CheckedByUser, MergeTypeID, Usercode, LastUpdated) VALUES (#MasterID, #ChildID, getDate(), 0, 0, #CheckedByUser, #MergeTypeID, '', " & _ "GetDate()) Else Update dbNicheMergeLog SET LastUpdated = getdate() WHERE MasterID=#MasterID AND ChildID = #ChildID"
objParameterValues.AssignParameterValues("#MasterID", tyNicheMergePOLE.MasterID, 1)
objParameterValues.AssignParameterValues("#ChildID", tyNicheMergePOLE.ChildID, 1)
objParameterValues.AssignParameterValues("#MergeTypeID", tyNicheMergePOLE.MergeTypeID, 1)
objParameterValues.AssignParameterValues("#CheckedByUser", 0, 1)
paramValues = objParameterValues.getParameterValues
intCount = clsDatabaseHelper.ExecuteNonQuery(objCon, CommandType.Text, strSQL, paramValues)
Return intCount
End Using
Catch ex As Exception
Return -2
Finally
' If objCon.State = ConnectionState.Open Then
' objCon.Close()
' End If
objCon = Nothing
End Try
End Function
Is there a way to determine whether an insertion or update took place?
if you are using sql server, you could use an output clause to determine if an update happened
Update dbNicheMergeLog SET LastUpdated =
getdate() WHERE MasterID=#MasterID AND
ChildID = #ChildID
OUTPUT count(*)
Then in vb use
dim updateCount as int = Convert.ToInt32(clsDatabaseHelper.ExecuteScalar())
Try this SQL:
WITH new (
MasterID
,ChildID
,DateAdded
,GenieUpdated
,done
,CheckedByUser
,MergeTypeID
,Usercode
,LastUpdated
)
AS(
SELECT
#MasterID
,#ChildID
,getDate()
,0
,0
,#CheckedByUser
,#MergeTypeID
,''
,getdate()
)
MERGE INTO dbNicheMergeLog t
USING new
ON t.MasterID = new.MasterID
AND t.ChildID = new.ChildID
WHEN NOT MATCHED BY TARGET THEN
INSERT (
MasterID
,ChildID
,DateAdded
,GenieUpdated
,done
,CheckedByUser
,MergeTypeID
,Usercode
,LastUpdated
)
VALUES (
new.MasterID
,new.ChildID
,new.DateAdded
,new.GenieUpdated
,new.done
,new.CheckedByUser
,new.MergeTypeID
,new.Usercode
,new.LastUpdated
)
OUTPUT $action as Action
;
You can use
Output deleted.*
in your update query to get the results that were lost on update, something like this:
Create Table #abctest(
Id int identity,Name varchar(200))
Insert into #abctest(Name)
Values('abcd'),('bcde'),('cdef'),('defg'),('efgh'),('fghi')
Update #abctest Set Name='xyz' OUTPUT Deleted.* Where Id=2
The above query will give you an output
Id Name
2 bcde
Related
I have and insert and update query.
I want to create a button that runs either the insert query or both the update and insert query.
On the form:
if cbx = values x, y or z, run insert and update.
if cbx does not = values x, y or z run only insert.
So far I have:
IF (Cbx=X OR Cbx =Y or cbx =Z) Then
Currentdb.execute("updateQuery")
Currentdb.execute("inserQuery")
ELSEIF (Cbx<>X OR Cbx <>Y or cbx <>Z) THEN
CurrentDB.execute("insertQuery")
ElSE
end if
When I run it the table get stuck in what seem like a continuous write/edit loop.
SQL
UPDATE
tbsurveypersonnel
SET tbsurveypersonnel.removedDate = DATE()
WHERE
(
(
(
tbsurveypersonnel.[sr]
)
=[Forms]![fatbSurveyPersonnelSetRoles]![sr]
)
AND
(
(
tbsurveypersonnel.[role]
)
=[Forms]![fatbSurveyPersonnelSetRoles]![role]
)
)
;
INSERT INTO tbsurveypersonnel
(
sr
, lfname
, role
, aDate
)
VALUES
(
(
(
tbsurveypersonnel.[sr]
)
=[Forms]![fatbSurveyPersonnelSetRoles]![sr]
)
, ((tbsurveypersonnel.[lfname])=[Forms]![fatbSurveyPersonnelSetRoles]![lfname])
)
,
(
(
tbsurveypersonnel.[role]
)
=[Forms]![fatbSurveyPersonnelSetRoles]![role]
)
), DATE()
final
Private Sub AssignRole_Click()
Dim strSql As String
Dim strlSQL2 As String
strSql = "UPDATE tbsurveypersonnel SET tbsurveypersonnel.removedDate = Now() " & vbCrLf & _
"WHERE removedDate is Null and (((tbsurveypersonnel.[sr])=[Forms]![fatbSurveyPersonnelSetRoles]![sr]) AND ((tbsurveypersonnel.[role])=[Forms]![fatbSurveyPersonnelSetRoles]![role]));"
strSQL2 = "INSERT INTO tbsurveypersonnel ( sr, lfname, role, assigndate ) " & vbCrLf & _
"SELECT [forms].[fatbSurveyPersonnelSetRoles].[sr] AS Expr1, [forms].[fatbSurveyPersonnelSetRoles].[lfName] AS Expr2, [forms].[fatbSurveyPersonnelSetRoles].[role] AS Expr3, Now() AS Expr4;"
If (Me.role = 1 Or Me.role = 2 Or Me.role = 3) Then
DoCmd.RunSQL strSql
DoCmd.RunSQL strSQL2
Else
DoCmd.RunSQL strSQL2
End If
DoCmd.RunCommand acCmdSaveRecord
DoCmd.Requery
End Sub
Answers the original question:
if cbx = values x, y or z, run insert and update.
So you want this:
IF (Cbx=X OR Cbx=Y OR cbx=Z) Then
Currentdb.execute("updateQuery")
Currentdb.execute("inserQuery")
ELSE
CurrentDB.execute("insertQuery")
end if
Avoid multiple calls toCurrentDbas everytime you create a copy (Instance, not Reference!) of the Database (DbEngine(0)(0) usually), what is usually not wanted and can raise errors.
Better store the instance in a variable or expand its scope.
With CurrentDb
If (Cbx=X Or Cbx=Y Or Cbx=Z) Then
.Execute("updateQuery", dbFailOnError)
End If
.Execute("insertQuery", dbFailOnError)
End With
AsinsertQueryis always executed, it is sufficent to just check ifupdateQueryneeds to be executed.
You don't need to ask the same question again.
If 'this criteria is met
Then
'Do some code
Else
'Do something else
End If
So in practice:
IF (Cbx<>X OR Cbx <>Y or cbx <>Z) Then
Currentdb.execute("updateQuery")
Currentdb.execute("inserQuery")
ELSE
CurrentDB.execute("insertQuery")
END IF
I am trying to update a selection of rows in an Oracle table we are using to handle messages. Because this table is busy, it would be best if the update could return the UniqueIDs of the rows it updated in an atomic transaction. I modified a code sample I found on StackOverflow to look like the following, but when I examine the parameter "p", I don't find any information coming back from the update statement, as I expected.
Any suggestions for modifying either the .NET code that is setting up the Oracle call, or modifying the Oracle SQL statement itself?
Dim connectString As String = data source=ORA1;user id=MESSAGEBOX;password=MESSAGEBOX
Dim conn As New OracleConnection(connectString)
If conn.State <> ConnectionState.Open Then
conn.Open()
End If
Dim transaction As OracleTransaction = conn.BeginTransaction()
Dim cmd As New OracleCommand()
cmd.Connection = conn
cmd.CommandText = "BEGIN UPDATE MESSAGE_TABLE SET C_WAS_PROCESSED = 2 WHERE C_ID IN (SELECT * FROM(SELECT C_ID FROM MESSAGE_TABLE WHERE C_WAS_PROCESSED = 0 AND C_CREATED_DATE_TIME < CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE) ORDER BY C_MESSAGE_PRIORITY, C_ID) WHERE ROWNUM < 16) RETURNING C_ID BULK COLLECT INTO :C_ID; END;"
cmd.CommandType = CommandType.Text
cmd.BindByName = True
cmd.ArrayBindCount = 15
Dim p As New OracleParameter()
p.ParameterName = "C_ID"
p.Direction = ParameterDirection.Output
p.OracleDbType = OracleDbType.Int64
p.Size = 15
p.ArrayBindSize = New Integer() {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}
p.CollectionType = OracleCollectionType.PLSQLAssociativeArray
cmd.Parameters.Add(p)
Dim nRowsAffected As Integer = cmd.ExecuteNonQuery()
transaction.Commit()
conn.Close()
conn.Dispose()
I believe that problem here is that SQL variable being RETURNED BULK COLLECT INTO needs to be of a TABLE type, not a simple number type.
Alter your SQL to include a declaration block like follows:
cmd.CommandText = "DECLARE TYPE IDS IS TABLE OF MESSAGE_TABLE.C_ID%TYPE; C_ID IDS;
BEGIN UPDATE MESSAGE_TABLE SET C_WAS_PROCESSED = 2 WHERE C_ID IN (SELECT * FROM(SELECT C_ID FROM MESSAGE_TABLE WHERE C_WAS_PROCESSED = 0 AND C_CREATED_DATE_TIME < CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE) ORDER BY C_MESSAGE_PRIORITY, C_ID) WHERE ROWNUM < 16) RETURNING C_ID BULK COLLECT INTO :C_ID; END;"
I got the table declaration syntax from this oracle-base.com link.
I'm having a problem executing a merge query from to update or insert values from a DataGridView table into a sql server database table. Here is my code below, it doesn't give me any errors or stoppages, however I recently noticed that it has been creating completely rows in my database table dbo.schedule which contain all NULL values even that key location, could someone please help me? I'm not very familiar with merge queries in sql so please point out issues with my syntax:
Dim query As String = String.Empty
query &= "DECLARE #TaskID nvarchar(8), #Task nvarchar(50), #Start_date datetime, #Due_date datetime, #Complete bit, #Task_Manager nvarchar(8), #JRID nvarchar(10), #Entered_By char(50), #Time_Entered datetime;"
query &= "MERGE INTO schedule USING (VALUES (#TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered)) AS t(TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered) "
query &= "ON schedule.TaskID = #TaskID WHEN MATCHED THEN"
query &= " UPDATE SET schedule.TaskID = t.TaskID, schedule.Task=t.Task, schedule.start_date=t.start_date, schedule.due_date=t.due_date, schedule.complete=t.complete, schedule.task_manager=t.task_manager, "
query &= "schedule.JRID=t.JRID, schedule.Entered_by=t.Entered_by, schedule.Time_Entered=t.Time_Entered"
query &= " WHEN NOT MATCHED THEN INSERT (TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered)"
query &= " VALUES (#TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered);"
Using conn As New SqlConnection(dbLocations(0, 1))
Using comm As New SqlCommand()
With comm
For Each row As DataGridViewRow In MainSchedule.DataGridView1.Rows
If Not (row.Cells(0).Value = Nothing) Then
.Parameters.Clear()
.Connection = conn
.CommandType = CommandType.Text
.CommandText = query
insertcommand.Parameters.AddWithValue("#TaskID", TNn)
insertcommand.Parameters.AddWithValue("#Complete", "False")
insertcommand.Parameters.AddWithValue("#Task", row.Cells(0).Value)
insertcommand.Parameters.AddWithValue("#Start_date", row.Cells(1).Value)
insertcommand.Parameters.AddWithValue("#Due_Date", row.Cells(2).Value)
insertcommand.Parameters.AddWithValue("#JRID", txtJRID.Text)
insertcommand.Parameters.AddWithValue("#Task_Manager", row.Cells(3).Value)
insertcommand.Parameters.AddWithValue("#Entered_By", GetUserName())
insertcommand.Parameters.AddWithValue("#Time_Entered", Now)
NextTask()
End If
Next
End With
conn.Open()
comm.ExecuteNonQuery()
End Using
End Using
I figured it out in case anyone is wondering, here is my new code:
Connexion.Open()
Dim query As String = String.Empty
Dim keypos = 0
query &= "UPDATE schedule SET Task = #Task, Complete = #Complete, Start_date = #Start_date, "
query &= "Due_date = #Due_date, JRID = #JRID, Task_Manager = #Task_Manager, Entered_By = #Entered_By, Time_Entered = #Time_Entered "
query &= "WHERE TaskID = #TaskID "
query &= "IF ##ROWCOUNT = 0 INSERT INTO schedule ( TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered)"
query &= " VALUES ( #TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered);"
For Each row As DataGridViewRow In MainSchedule.DataGridView1.Rows
If Not (row.Cells(0).Value = Nothing) Then
insertcommand.Parameters.Clear()
insertcommand.CommandText = query
insertcommand.Parameters.AddWithValue("#TaskID", row.Cells(0).Value)
insertcommand.Parameters.AddWithValue("#Complete", "False")
insertcommand.Parameters.AddWithValue("#Task", row.Cells(1).Value)
insertcommand.Parameters.AddWithValue("#Start_date", row.Cells(2).Value)
insertcommand.Parameters.AddWithValue("#Due_Date", row.Cells(3).Value)
insertcommand.Parameters.AddWithValue("#JRID", txtJRID.Text)
insertcommand.Parameters.AddWithValue("#Task_Manager", row.Cells(4).Value)
insertcommand.Parameters.AddWithValue("#Entered_By", GetUserName())
insertcommand.Parameters.AddWithValue("#Time_Entered", Now)
insertcommand.ExecuteNonQuery()
End If
keypos = keypos + 1
Next
Connexion.Close()
I have a Stored Procedure that I am executing from VB.NET. The SP should insert records into a table and return a set to the calling app. The set returned are the records that were inserted.
If the INSERT fails, the exception is caught and re-thrown in the SP, but I never see the exception in my application. The severity level is 14, so I should see it.
Here is the stored procedure:
BEGIN TRY
BEGIN TRANSACTION
-- Declare local variables
DECLARE #DefaultCategoryID AS BIGINT = 1 -- 1 = 'Default Category' (which means no category)
DECLARE #DefaultWeight AS DECIMAL(18,6) = 0
DECLARE #InsertionDate AS DATETIME2(7) = GETDATE()
DECLARE #SendToWebsite AS BIT = 0 -- 0 = 'NO'
DECLARE #MagentoPartTypeID AS BIGINT = 1 -- For now, this is the only part type we are importing from COPICS ('simple' part type)
DECLARE #NotUploaded_PartStatusID AS TINYINT = 0 -- 0 = 'Not Uploaded'
DECLARE #Enabled_PartStatusID AS TINYINT = 1 -- 1 = 'Enabled'
DECLARE #Disabled_PartStatusID AS TINYINT = 2 -- 2 = 'Disabled'
-- Get the part numbers that will be inserted (this set will be returned to calling procedure).
SELECT c.PartNumber
FROM
COPICSPartFile c
LEFT JOIN Part p on c.PartNumber = p.PartNumber
WHERE
p.PartNumber IS NULL
-- Insert new records from COPICSPartFile (records that don't exist - by PartNumber - in Part table)
INSERT INTO Part
([PartNumber]
,[ReplacementPartNumber]
,[ShortDescription]
,[ListPrice]
,[PartStatusTypeID]
,[Weight]
,[CategoryID]
,[DateInserted]
,[SendToWebsite]
,[FileName]
,[MagentoPartTypeID]
,[PrintNumber])
SELECT
c.PartNumber
,c.ReplacementPartNumber
,c.ShortDescription
,c.ListPrice
,CASE WHEN c.PartStatusTypeID = #Enabled_PartStatusID THEN #NotUploaded_PartStatusID ELSE #Disabled_PartStatusID END
,#DefaultWeight
,#DefaultCategoryID
,#InsertionDate
,#SendToWebsite
,#FileName
,#MagentoPartTypeID
,c.PrintNumber
FROM
COPICSPartFile c
LEFT JOIN Part p on c.PartNumber = p.PartNumber
WHERE
p.PartNumber IS NULL
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION;
THROW;
END CATCH
And here is the .net code:
Try
'Create command
Dim command As New SqlCommand
command.CommandType = CommandType.StoredProcedure
conn = New SqlConnection(m_ConnectionString)
command.Connection = conn
command.CommandText = "trxInsertPartFromCOPICSPartFile"
With command.Parameters
.AddWithValue("#FileName", fileName)
End With
Dim da As New SqlDataAdapter(command)
Dim dt As New DataTable
da.Fill(dt)
If dt.Rows.Count > 0 Then
Return dt
Else
Return Nothing
End If
Catch ex As SqlException
Dim myMessage As String = ex.Message
Finally
If conn.State <> ConnectionState.Closed Then
conn.Close()
End If
End Try
As I was trying to figure out why the exception (duplicate key) wasn't being caught in my application, I tried commenting out the SELECT statement in the SP just before the INSERT and voila. The exception from the INSERT is caught in the application.
Can someone explain to me why the SELECT statement causes this? I know I can break out the SELECT into another SP, but I'd like to keep it all one atomic transaction if possible. Is this expected behavior? Is there a way around it?
Thanks.
The exception is being swallowed by the Fill method. Instead of using that method, create a SqlDataReader, do a command.ExecuteReader(), and then use the reader to populate the DataTable via Load(). This way the error should occur in the ExecuteReader() method and should be catchable. And then you shouldn't need the SqlDataAdapter.
Try
'Create command
Dim command As New SqlCommand
command.CommandType = CommandType.StoredProcedure
conn = New SqlConnection(m_ConnectionString)
command.Connection = conn
command.CommandText = "trxInsertPartFromCOPICSPartFile"
With command.Parameters
.AddWithValue("#FileName", fileName)
End With
Dim dt As New DataTable
conn.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
dt.Load(reader)
If dt.Rows.Count > 0 Then
Return dt
Else
Return Nothing
End If
Catch ex As SqlException
Dim myMessage As String = ex.Message
Finally
If conn.State <> ConnectionState.Closed Then
conn.Close()
End If
End Try
Also, you might be better off on several levels if you combine the SELECT and the INSERT into a single statement. You can do this via the OUTPUT clause, as follows:
INSERT INTO Part
([PartNumber]
,[ReplacementPartNumber]
,[ShortDescription]
,[ListPrice]
,[PartStatusTypeID]
,[Weight]
,[CategoryID]
,[DateInserted]
,[SendToWebsite]
,[FileName]
,[MagentoPartTypeID]
,[PrintNumber])
OUTPUT INSERTED.[PartNumber] -- return the inserted values to the app code
SELECT
c.PartNumber
,c.ReplacementPartNumber
,c.ShortDescription
,c.ListPrice
,CASE WHEN c.PartStatusTypeID = #Enabled_PartStatusID
THEN #NotUploaded_PartStatusID
ELSE #Disabled_PartStatusID END
,#DefaultWeight
,#DefaultCategoryID
,#InsertionDate
,#SendToWebsite
,#FileName
,#MagentoPartTypeID
,c.PrintNumber
FROM
COPICSPartFile c
LEFT JOIN Part p on c.PartNumber = p.PartNumber
WHERE
p.PartNumber IS NULL
I have the following problem:
Inside one sqltransaction in vb.net I INSERT data into several tables.
it is something like this:
...
sqltransaction = connection.begintransaction
INSERT into table1
...
for i=1 to x
...
INSERT into table2
...
SELECT FROM table3
...
INSERT into table3
...
next i
sqltransaction.commit
...
Private Sub salveazaCerereaDeOferta()
If checkCompletion() = 1 Then
Dim conn As New SqlConnection(My.Settings.GestiuneService2012_beSQLConnectionString)
conn.Open()
Dim sqlTrans As SqlTransaction = conn.BeginTransaction()
Try
Dim cmdInsertCerereOferta As SqlCommand = conn.CreateCommand
cmdInsertCerereOferta.Transaction = sqlTrans
cmdInsertCerereOferta.CommandText = "INSERT INTO ListaCereriOferte (IDFurnizor,NrCerereOferta,DataCerereOferta,IDModTransCerereOferta,ObservatiiCerereOferta)" + _
" VALUES (#IDFurnizor,#NrCerereOferta,#DataCerereOferta,#IDModTransCerereOferta,#ObservatiiCerereOferta);" + _
" SELECT SCOPE_IDENTITY();"
cmdInsertCerereOferta.Parameters.Add("#IDFurnizor", SqlDbType.Int).Value = CInt(Me.t_IDFurnizor.Text)
cmdInsertCerereOferta.Parameters.Add("#NrCerereOferta", SqlDbType.Int).Value = CInt(Me.t_NumarCerereOferta.Text)
cmdInsertCerereOferta.Parameters.Add("#DataCerereOferta", SqlDbType.Date).Value = CDate(Me.t_DataCerereOferta.Text)
cmdInsertCerereOferta.Parameters.Add("#IDModTransCerereOferta", SqlDbType.Int).Value = 1
cmdInsertCerereOferta.Parameters.Add("#ObservatiiCerereOferta", SqlDbType.NVarChar).Value = Me.t_ObservatiiCerereOferta.Text
Dim IDCerereOferta As Integer = cmdInsertCerereOferta.ExecuteScalar
Dim ListaPieseCerereOferta = Me.CerereOfertaDataSet.ListaPieseCerereOferta.AsEnumerable
Dim ListaNecesarePePiesa = Me.CerereOfertaDataSet.NecesarePeOferta.AsEnumerable
Dim PieseOferta = From q In ListaPieseCerereOferta _
Select q
Dim cantTotalaPiese = Aggregate q In ListaPieseCerereOferta _
Into Sum(q.Cantitate)
Dim salvat As Integer = 0
Dim curIDPiesaDeSchimb As Integer
For Each piesa In PieseOferta
curIDPiesaDeSchimb = piesa.IDPiesaDeSchimb
Dim NecesarePePiesa = From p In ListaNecesarePePiesa _
Select p _
Order By p.IDNecesar Descending
Dim curIDNecesar As Integer
For Each necesar In NecesarePePiesa
curIDNecesar = necesar.IDNecesar
Dim cmdInsertPiesaCerereOferta As SqlCommand = conn.CreateCommand
cmdInsertPiesaCerereOferta.Transaction = sqlTrans
cmdInsertPiesaCerereOferta.CommandText = "INSERT INTO CereriOferte (IDCerereOferta,IDPiesaDeSchimb,Cantitate,UM,Observatii)" + _
" VALUES (#IDCerereOferta,#IDPiesaDeSchimb,#Cantitate,#UM,#Observatii);" + _
" SELECT SCOPE_IDENTITY();"
cmdInsertPiesaCerereOferta.Parameters.Add("#IDCerereOferta", SqlDbType.Int)
cmdInsertPiesaCerereOferta.Parameters.Add("#IDPiesaDeSchimb", SqlDbType.Int)
cmdInsertPiesaCerereOferta.Parameters.Add("#Cantitate", SqlDbType.Float)
cmdInsertPiesaCerereOferta.Parameters.Add("#UM", SqlDbType.NVarChar)
cmdInsertPiesaCerereOferta.Parameters.Add("#Observatii", SqlDbType.NVarChar)
Dim cmdInsertNecesarCerereOferta As SqlCommand = conn.CreateCommand
cmdInsertNecesarCerereOferta.Transaction = sqlTrans
cmdInsertNecesarCerereOferta.CommandText = "INSERT INTO NecesareCereriOferte (IDPiesaNecesar,IDPiesaCerereOferta)" + _
" VALUES (#IDPiesaNecesar,#IDPiesaCerereOferta)"
cmdInsertNecesarCerereOferta.Parameters.Add("#IDPiesaNecesar", SqlDbType.Int)
cmdInsertNecesarCerereOferta.Parameters.Add("#IDPiesaCerereOferta", SqlDbType.Int)
Select Case curIDNecesar
Case 0
cmdInsertPiesaCerereOferta.Parameters("#IDCerereOferta").Value = IDCerereOferta
cmdInsertPiesaCerereOferta.Parameters("#IDPiesaDeSchimb").Value = curIDPiesaDeSchimb
cmdInsertPiesaCerereOferta.Parameters("#Cantitate").Value = 1
cmdInsertPiesaCerereOferta.Parameters("#UM").Value = piesa.UM
cmdInsertPiesaCerereOferta.Parameters("#Observatii").Value = ""
For i = 1 To necesar.Cantitate
cmdInsertPiesaCerereOferta.ExecuteNonQuery()
salvat += 1
Me.tsspb_SalvareCerereOferta.Value = CInt(100 * salvat / cantTotalaPiese)
Next
Case Is > 0
Me.PieseNecesarePeOfertaTableAdapter.Fill(Me.CerereOfertaDataSet.PieseNecesarePeOferta, curIDNecesar, curIDPiesaDeSchimb, CInt(necesar.Cantitate))
Dim ListaPieseNecesarePeOferta = Me.CerereOfertaDataSet.PieseNecesarePeOferta.AsEnumerable
Dim PieseNecesareOferta = From q In ListaPieseNecesarePeOferta _
Select q
For i = 1 To necesar.Cantitate
cmdInsertPiesaCerereOferta.Parameters("#IDCerereOferta").Value = IDCerereOferta
cmdInsertPiesaCerereOferta.Parameters("#IDPiesaDeSchimb").Value = curIDPiesaDeSchimb
cmdInsertPiesaCerereOferta.Parameters("#Cantitate").Value = 1
cmdInsertPiesaCerereOferta.Parameters("#UM").Value = piesa.UM
cmdInsertPiesaCerereOferta.Parameters("#Observatii").Value = ""
Dim insertedIDPiesaCerereOferta As Integer = cmdInsertPiesaCerereOferta.ExecuteScalar
cmdInsertNecesarCerereOferta.Parameters("#IDPiesaNecesar").Value = PieseNecesareOferta(i - 1).IDPiesaNecesar
cmdInsertNecesarCerereOferta.Parameters("#IDPiesaCerereOferta").Value = insertedIDPiesaCerereOferta
cmdInsertNecesarCerereOferta.ExecuteNonQuery()
salvat += 1
Me.tsspb_SalvareCerereOferta.Value = CInt(100 * salvat / cantTotalaPiese)
Next
End Select
Next
Next
sqlTrans.Commit()
MsgBox("Cererea de oferta a fost salvata.")
Catch ex As Exception
Try
sqlTrans.Rollback()
MsgBox("A aparut o eroare." + vbNewLine + ex.ToString + vbNewLine + "RollBack success. Cererea nu a fost salvata.")
Catch ex2 As SqlException
If Not sqlTrans.Connection Is Nothing Then
MsgBox("An exception of type " & ex2.GetType().ToString() & _
" was encountered while attempting to roll back the transaction.")
End If
End Try
Finally
If conn.State = ConnectionState.Open Then conn.Close()
End Try
Else
MsgBox("Nu ai completat integral cererea de oferta!")
End If
End Sub
query that locks:
SELECT TOP (100) PERCENT dbo.qry_NecesareNerezolvate.IDPiesaNecesar, COUNT(dbo.NecesareCereriOferte.IDPiesaCerereOferta) AS CereriOferte,
dbo.qry_NecesareNerezolvate.IDNecesar, dbo.qry_NecesareNerezolvate.IDPiesaDeSchimb, dbo.qry_NecesareNerezolvate.Cantitate
FROM dbo.qry_NecesareNerezolvate LEFT OUTER JOIN
dbo.NecesareCereriOferte ON dbo.qry_NecesareNerezolvate.IDPiesaNecesar = dbo.NecesareCereriOferte.IDPiesaNecesar
GROUP BY dbo.qry_NecesareNerezolvate.IDPiesaNecesar, dbo.qry_NecesareNerezolvate.IDNecesar, dbo.qry_NecesareNerezolvate.IDPiesaDeSchimb,
dbo.qry_NecesareNerezolvate.Cantitate
qry_NecesareNerezolvate:
SELECT TOP (100) PERCENT dbo.Necesare.IDPiesaNecesar, dbo.Necesare.IDNecesar, dbo.Necesare.IDPiesaDeSchimb, dbo.Necesare.Cantitate, dbo.Necesare.UM,
dbo.Necesare.Observatii
FROM dbo.Necesare LEFT OUTER JOIN
dbo.qry_NecesareComandateRezolvate ON dbo.Necesare.IDPiesaNecesar = dbo.qry_NecesareComandateRezolvate.IDPiesaNecesar
WHERE (dbo.qry_NecesareComandateRezolvate.IDPiesaNecesar IS NULL)
qry_NecesareComandateRezolvate:
SELECT dbo.Necesare.IDPiesaNecesar, dbo.NecesareComenzi.IDPiesaComanda, dbo.NecesareRezolvate.IDBonTransfer
FROM dbo.Necesare LEFT OUTER JOIN
dbo.NecesareComenzi ON dbo.Necesare.IDPiesaNecesar = dbo.NecesareComenzi.IDPiesaNecesar LEFT OUTER JOIN
dbo.NecesareRezolvate ON dbo.Necesare.IDPiesaNecesar = dbo.NecesareRezolvate.IDPiesaNecesar
WHERE (dbo.NecesareComenzi.IDPiesaComanda IS NOT NULL) OR
(dbo.NecesareRezolvate.IDBonTransfer IS NOT NULL)
for i=1: insert, select then insert is working
then i=2 and: INSERT into table2... is working but SELECT FROM table1 and table3... gets timeout...
I don't understand why!
PS: If I break the code before second run of SELECT FROM table3 then go to SSMS and run the select query it gets timeout too...
In your code sample below, you have the transaction open till the end of the For Loop.
It seems to me that when i =1 , the transaction gets opened and a insertion is made. Now when i=2 , the to be inserted row when i=1 is in uncomitted state and if your select is joining to the table1 the lock level would have escalated to table level and locked everything down. Move the commit to inside the for loop and check how it goes.
for i=1 to x
...
INSERT into table2
...
SELECT FROM table3
...
INSERT into table3
...
next i
sqltransaction.commit