I have a SQL command that I'm running in VB.NET... I've written this type of command countless times, however, I'm getting an error when trying to process the command below:
Dim VIconn As New SqlConnection("Data Source=MBSRVERP01;Initial Catalog=MBUk;Integrated Security=True")
Dim CMDoperation As SqlCommand = New SqlCommand()
CMDoperation.Connection = VIconn
CMDoperation.CommandText = ("INSERT INTO PRJCREATION.dbo.OPERATION_CO (WORKORDER_TYPE, WORKORDER_BASE_ID, WORKORDER_LOT_ID, WORKORDER_SPLIT_ID, WORKORDER_SUB_ID, SEQUENCE_NO, RESOURCE_ID, SETUP_HRS, " _
& "RUN, RUN_TYPE, LOAD_SIZE_QTY, RUN_HRS, MOVE_HRS, TRANSIT_DAYS, SERVICE_ID, SCRAP_YIELD_PCT, SCRAP_YIELD_TYPE, FIXED_SCRAP_UNITS, MINIMUM_MOVE_QTY, CALC_START_QTY, " _
& "CALC_END_QTY, COMPLETED_QTY, DEVIATED_QTY, ACT_SETUP_HRS, ACT_RUN_HRS, STATUS, SETUP_COMPLETED, SERVICE_BEGIN_DATE, CLOSE_DATE, OPERATION_TYPE, DRAWING_ID, DRAWING_REV_NO, " _
& "OVERRIDE_QTYS, BEGIN_TRACEABILITY, CAPACITY_USAGE_MAX, CAPACITY_USAGE_MIN, TEST_ID, SPC_QTY, SCHED_START_DATE, SCHED_FINISH_DATE, COULD_FINISH_DATE, ISDETERMINANT, " _
& "SETUP_COST_PER_HR, RUN_COST_PER_HR, RUN_COST_PER_UNIT, BUR_PER_HR_SETUP, BUR_PER_HR_RUN, BUR_PER_UNIT_RUN, SERVICE_BASE_CHG, BUR_PERCENT_SETUP, BUR_PERCENT_RUN, " _
& "BUR_PER_OPERATION, EST_ATL_LAB_COST, EST_ATL_BUR_COST, EST_ATL_SER_COST, REM_ATL_LAB_COST, REM_ATL_BUR_COST, REM_ATL_SER_COST, ACT_ATL_LAB_COST, ACT_ATL_BUR_COST, " _
& "ACT_ATL_SER_COST, EST_TTL_MAT_COST, EST_TTL_LAB_COST, EST_TTL_BUR_COST, EST_TTL_SER_COST, REM_TTL_MAT_COST, REM_TTL_LAB_COST, REM_TTL_BUR_COST, REM_TTL_SER_COST, " _
& "ACT_TTL_MAT_COST, ACT_TTL_LAB_COST, ACT_TTL_BUR_COST, ACT_TTL_SER_COST, SPLIT_ADJUSTMENT, MILESTONE_ID, SCHEDULE_TYPE, MIN_SEGMENT_SIZE, PROTECT_COST, DRAWING_FILE, " _
& "DISPATCHED_QTY, SERVICE_MIN_CHG, VENDOR_ID, VENDOR_SERVICE_ID, SERVICE_PART_ID, LAST_DISP_DATE, LAST_RECV_DATE, WAREHOUSE_ID, ALLOCATED_QTY, FULFILLED_QTY, " _
& "LEAST_MIN_MOVE_QTY, MAX_GAP_PREV_OP, APPLY_CALENDAR, MAX_DOWNTIME, ACCUM_DOWNTIME, RUN_QTY_PER_CYCLE, USER_1, USER_2, USER_3, USER_4, USER_5, USER_6, USER_7, USER_8, " _
& "USER_9, USER_10, UDF_LAYOUT_ID, NUM_MEM_TO_SCHED, SERVICE_BUFFER, MILESTONE_SUB_ID, POST_MILESTONE, PROJ_MILESTONE_OP, WBS_CODE, WBS_START_DATE, WBS_END_DATE, " _
& "WBS_DURATION, MILESTONE_SEQ_NO, PRD_INSP_PLAN_ID, SETUP_INSPECT_REQ, RUN_INSPECT_REQ, STATUS_EFF_DATE, PRED_SUB_ID, PRED_SEQ_NO, SITE_ID, SCHED_CAPACITY_USAGE)" _
& "SELECT WORKORDER_TYPE, WORKORDER_BASE_ID + 'F', WORKORDER_LOT_ID, WORKORDER_SPLIT_ID, WORKORDER_SUB_ID, SEQUENCE_NO, RESOURCE_ID, SETUP_HRS, " _
& "RUN, RUN_TYPE, LOAD_SIZE_QTY, RUN_HRS, MOVE_HRS, TRANSIT_DAYS, SERVICE_ID, SCRAP_YIELD_PCT, SCRAP_YIELD_TYPE, FIXED_SCRAP_UNITS, MINIMUM_MOVE_QTY, CALC_START_QTY, " _
& "CALC_END_QTY, COMPLETED_QTY, DEVIATED_QTY, ACT_SETUP_HRS, ACT_RUN_HRS, 'R', SETUP_COMPLETED, SERVICE_BEGIN_DATE, NULL, OPERATION_TYPE, DRAWING_ID, DRAWING_REV_NO, " _
& "OVERRIDE_QTYS, BEGIN_TRACEABILITY, CAPACITY_USAGE_MAX, CAPACITY_USAGE_MIN, TEST_ID, SPC_QTY, NULL, NULL, NULL, ISDETERMINANT, " _
& "SETUP_COST_PER_HR, RUN_COST_PER_HR, RUN_COST_PER_UNIT, BUR_PER_HR_SETUP, BUR_PER_HR_RUN, BUR_PER_UNIT_RUN, SERVICE_BASE_CHG, BUR_PERCENT_SETUP, BUR_PERCENT_RUN, " _
& "BUR_PER_OPERATION, EST_ATL_LAB_COST, EST_ATL_BUR_COST, EST_ATL_SER_COST, REM_ATL_LAB_COST, REM_ATL_BUR_COST, REM_ATL_SER_COST, ACT_ATL_LAB_COST, ACT_ATL_BUR_COST, " _
& "ACT_ATL_SER_COST, EST_TTL_MAT_COST, EST_TTL_LAB_COST, EST_TTL_BUR_COST, EST_TTL_SER_COST, REM_TTL_MAT_COST, REM_TTL_LAB_COST, REM_TTL_BUR_COST, REM_TTL_SER_COST, " _
& "ACT_TTL_MAT_COST, ACT_TTL_LAB_COST, ACT_TTL_BUR_COST, ACT_TTL_SER_COST, SPLIT_ADJUSTMENT, MILESTONE_ID, SCHEDULE_TYPE, MIN_SEGMENT_SIZE, PROTECT_COST, DRAWING_FILE, " _
& "DISPATCHED_QTY, SERVICE_MIN_CHG, VENDOR_ID, VENDOR_SERVICE_ID, SERVICE_PART_ID, LAST_DISP_DATE, LAST_RECV_DATE, WAREHOUSE_ID, ALLOCATED_QTY, FULFILLED_QTY, " _
& "LEAST_MIN_MOVE_QTY, MAX_GAP_PREV_OP, APPLY_CALENDAR, MAX_DOWNTIME, ACCUM_DOWNTIME, RUN_QTY_PER_CYCLE, USER_1, USER_2, USER_3, USER_4, USER_5, USER_6, USER_7, USER_8, " _
& "USER_9, USER_10, UDF_LAYOUT_ID, NUM_MEM_TO_SCHED, SERVICE_BUFFER, MILESTONE_SUB_ID, POST_MILESTONE, PROJ_MILESTONE_OP, WBS_CODE, WBS_START_DATE, WBS_END_DATE, " _
& "WBS_DURATION, MILESTONE_SEQ_NO, PRD_INSP_PLAN_ID, SETUP_INSPECT_REQ, RUN_INSPECT_REQ, STATUS_EFF_DATE, PRED_SUB_ID, PRED_SEQ_NO, SITE_ID, SCHED_CAPACITY_USAGE" _
& "FROM MBUK.dbo.OPERATION db2 " _
& "WHERE (db2.WORKORDER_BASE_ID = '" & rw.Cells(8).Value & "')")
CMDoperation.ExecuteNonQuery()
The error I get is {"Incorrect syntax near '.'."}
The SQL command is simply inserting data from a table in database A into a table in database B... Nothing complex.
Can anyone spot where I'm going wrong here?
Thanks
Here my 2 cents:
pay attention to VB concatenation, the end of the line is strictly attached to the following one, so in your code
& "WBS_DURATION, MILESTONE_SEQ_NO, PRD_INSP_PLAN_ID, SETUP_INSPECT_REQ, RUN_INSPECT_REQ, STATUS_EFF_DATE, PRED_SUB_ID, PRED_SEQ_NO, SITE_ID, SCHED_CAPACITY_USAGE" _
& "FROM MBUK.dbo.OPERATION db2 " _
vb ends concatenating words in this way: SCHED_CAPACITY_USAGEFROM
so add an extra space at the end of each line you concatenate.
I am trying to execute multiple SQL statements against a SQL server database using ADODB and vb6.
when I open a recordset the code stops with the following error code:
Run-time error '3704':
Operation is not allowed when object is closed.
here is my code:
Dim sql As String
sql = "WITH " & vbCrLf & _
"q AS" & vbCrLf & _
"(SELECT Item_No, Unit_OldQuantity" & vbCrLf & _
"FROM dbo.The_Units), sequenced AS" & vbCrLf & _
"(SELECT ROW_NUMBER() OVER (PARTITION BY Item_No ORDER BY Unit_OldQuantity DESC) AS sequence_id,*" & vbCrLf & _
"From q)" & vbCrLf & _
"SELECT Item_No , Unit_OldQuantity" & vbCrLf & _
"into #tmpTable" & vbCrLf & _
"From sequenced" & vbCrLf & _
"Where sequence_id = 1" & vbCrLf & _
"SELECT sum(The_ItemDetails.Item_Cost / #tmpTable.Unit_OldQuantity * The_ItemDetails.Item_Quantity) AS Total" & vbCrLf & _
"FROM The_Items INNER JOIN The_ItemDetails ON The_Items.Item_No = The_ItemDetails.Item_No INNER JOIN #tmpTable ON The_ItemDetails.Item_No = #tmpTable.Item_No" & vbCrLf & _
"Where the_items.Item_kind = 0"
Dim connText As String
connText = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=AlmohasebSQL;Data Source=server-pc\SQLEXPRESS"
Db_Almohaseb.ConnectionString = connText
Db_Almohaseb.Open
Dim RS_ItemDetails As New ADODB.Recordset
RS_ItemDetails.Open sql, Db_Almohaseb, adOpenStatic, adLockOptimistic, adCmdText
Text1.Text = RS_ItemDetails.RecordCount
I can run any other sql statement using the same connection but not this one.
I can also run this command in .net but not in vb6.
Right now I just need to know why this is happening, and I am feeling woozy from banging my head against the desk.
please can someone shed some light on this.
Thanks
When you have a sql statement with multiple sql statements, you need to use SET NOCOUNT ON, like this:
sql = "SET NOCOUNT ON;" & _
"WITH " & vbCrLf & _
"q AS" & vbCrLf & _
"(SELECT Item_No, Unit_OldQuantity" & vbCrLf & _
"FROM dbo.The_Units), sequenced AS" & vbCrLf & _
"(SELECT ROW_NUMBER() OVER (PARTITION BY Item_No ORDER BY Unit_OldQuantity DESC) AS sequence_id,*" & vbCrLf & _
"From q)" & vbCrLf & _
"SELECT Item_No , Unit_OldQuantity" & vbCrLf & _
"into #tmpTable" & vbCrLf & _
"From sequenced" & vbCrLf & _
"Where sequence_id = 1" & vbCrLf & _
"SELECT sum(The_ItemDetails.Item_Cost / #tmpTable.Unit_OldQuantity * The_ItemDetails.Item_Quantity) AS Total" & vbCrLf & _
"FROM The_Items INNER JOIN The_ItemDetails ON The_Items.Item_No = The_ItemDetails.Item_No INNER JOIN #tmpTable ON The_ItemDetails.Item_No = #tmpTable.Item_No" & vbCrLf & _
"Where the_items.Item_kind = 0"
Remove the "#" :
#tmpTable.Unit_OldQuantity
should be
tmpTable.Unit_OldQuantity
The only available solution to my problem is to move the statements to a stored procedure.
So I check if the procedure exists in the targeted db, if not I will create the procedure; else, I execute the procedure with the proper parameters.
I have also included the logic for checking the temp file if it exists in the db.
I have a table in MS Access 2003 in which I want to archive all old data.
The criteria is that the creation data should be less than a specific date.
I can write a SQL statement to select them, but I don't know how to move them to another database/table? Assuming that the archive database/table is already created and data structure matches current table.
Also how I can make sure that all data which is moved to archive table is removed from current table?
I want to write VBA code to run the command check that data is archived correctly.
You want to 1) move data meeting certain criteria from one table to another, existing table with the same format. 2) You want to "make sure that all data which is moved to archive table is removed from current table." And 3) you "want to write VBA code to run the command check that data is archived correctly."
Contrary to popular opinion, Access does support transactions (the claim that Access SQL does not support transactions is true, but we can still use transactions in VBA code). So modifying code in this post to use transactions in a workspace, I believe this would do the trick (tested in Access 2010 using DAO).
The code to lock, get counts and unlock is not really necessary, and may increase the difficulty of implementing the archive, since it will require that no one be writing to the table while you're updating it. And if it did find a problem, Access does not support transaction logging, so you would have a very short list of options as to how to fix it. But it sounded like you wanted to be absolutely sure the counts were correct, so this adds another level, arguably unnecessary, of checking.
Option Compare Database
Option Explicit
Sub ArchiveOldRecords()
Dim nSourceCount As Long, nMoveCount As Long, nDestCount As Long
Dim strSQL As String, sMsg As String
Dim rsLock As DAO.Recordset
Dim rsBefore As DAO.Recordset, rsAfter As DAO.Recordset
Dim wrk As Workspace, db As DAO.Database
Const strcTableSource As String = "t_TestWithDate" ' Move records FROM table
Const strcTableArch As String = "t_ArchiveTestWithDate" ' Move records TO table
Const strcWHERE As String = " WHERE field2 < " _
& "DATEADD(""yyyy"", -1, Date())" ' Select date field and DATEADD params
Const strcCount As String = "SELECT COUNT(*) As "
On Error GoTo TrapError
Set db = CurrentDb
Set wrk = DBEngine.Workspaces(0)
' Lock table - so no one can add/delete records until count is verified
Set rsLock = db.OpenRecordset(strcTableSource, dbOpenTable, dbDenyWrite)
' Get initial table counts
Set rsBefore = db.OpenRecordset( _
strcCount & "SourceCount, " _
& "(SELECT COUNT(*) FROM " & strcTableSource _
& strcWHERE & ") As MoveCount, " _
& "(SELECT COUNT(*) FROM " & strcTableArch & ") As DestCount " _
& "FROM " & strcTableSource & ";", dbOpenForwardOnly)
nSourceCount = rsBefore!SourceCount
nMoveCount = rsBefore!MoveCount
nDestCount = rsBefore!DestCount
rsBefore.Close
wrk.BeginTrans
' Copy records
strSQL = "INSERT INTO " & strcTableArch _
& " SELECT * FROM " & strcTableSource & " " & strcWHERE & ";"
db.Execute strSQL, dbFailOnError
' Unlock table - only needed for counts
rsLock.Close
Set rsLock = Nothing
' Delete copied records
strSQL = "DELETE * FROM " & strcTableSource & " " & strcWHERE & ";"
db.Execute strSQL, dbDenyWrite + dbFailOnError
' Lock table - only needed for counts
Set rsLock = db.OpenRecordset(strcTableSource, dbOpenTable, dbDenyWrite)
wrk.CommitTrans
' Get final table counts
Set rsAfter = db.OpenRecordset( _
strcCount & "SourceCount, " _
& "(SELECT COUNT(*) FROM " & strcTableSource _
& strcWHERE & ") As MoveCount, " _
& "(SELECT COUNT(*) FROM " & strcTableArch & ") As DestCount " _
& "FROM " & strcTableSource & ";", dbOpenForwardOnly)
' Double-check counts
If (rsAfter!SourceCount <> nSourceCount - nMoveCount) _
Or (rsAfter!DestCount <> nDestCount + nMoveCount) _
Or (rsAfter!MoveCount > 0) Then
sMsg = vbNewLine
sMsg = sMsg & "Records in " & strcTableSource & " before: "
sMsg = sMsg & nSourceCount
sMsg = sMsg & vbTab & "after: "
sMsg = sMsg & rsAfter!SourceCount
sMsg = sMsg & vbNewLine
sMsg = sMsg & "Records to archive from " & strcTableSource & ": "
sMsg = sMsg & nMoveCount
sMsg = sMsg & vbTab & "after: "
sMsg = sMsg & rsAfter!MoveCount
sMsg = sMsg & vbNewLine
sMsg = sMsg & "Records in " & strcTableArch & " before: "
sMsg = sMsg & nDestCount
sMsg = sMsg & vbTab & "after: "
sMsg = sMsg & rsAfter!DestCount
MsgBox "Count double-check failed" & sMsg
End If
Exit_Sub:
On Error Resume Next
' Unlock table and close recordsets
rsLock.Close
rsBefore.Close
rsAfter.Close
Set rsBefore = Nothing
Set rsAfter = Nothing
Set rsLock = Nothing
Set db = Nothing
Set wrk = Nothing
Exit Sub
TrapError:
MsgBox "Failed: " & Err.Description
wrk.Rollback
Err.Clear
Resume Exit_Sub
End Sub
There is no MOVE command but you can copy the records across to the target and then use a similar query to remove them from the source when you are sure you have no Paste Errors.
INSERT INTO MyArchive (fld1, fld2, fld3, fld4) SELECT fld1, fld2, fld3, fld4 FROM MyTable WHERE fld4 < DATEADD("y", -5, Date())
That copies across everything older than 5 years. After confirming the transfer,
DELETE * FROM MyTable WHERE fld4 < DATEADD("y", -5, Date())
That's off the top of my head and I transition between T-SQL and MS Access a fair bit but I think that is pretty solid Access query code. Your own field lists will vary accordingly.