Creating Receipt Id for each Transaction - sql

Background
I am using an Excel UI and VB ADODB back-end so users can insert data into SQL Server.
Since users are free to use as many rows as they would like (business requirement), I ended up using a FOR loop to iterate through the rows and insert them one by one.
Initial Code
For i = 7 To LastRow
Command.CommandText = "INSERT INTO [dbo].[TEP_Payments_Table] ([AA Number], " & _
"[AA Name], [Request Receipt Id])" & _
"VALUES (" & _
"'" & Sheets("Project_Name").Cells(i, 2).Value & "'," & _
"'" & Sheets("Project_Name").Cells(i, 3).Value & "'," & _
"'" & Sheets("Project_Name").Cells(i, 6).Value & "')"
Command.Execute
The 'Request Receipt Id' column is filled by Col6 in 'Project_Name' sheet. That was auto filled by by looking at the last id in TEP_Payments_Table and +1.
This resulted in duplicates if multiple users use it simultaneously.
I managed to get workout how to user OUTPUT INSERTED in a standard INSERT INTO clause to generate an id for each transaction; using the following syntax:
declare #ids table (id int);
insert into [dbo].[TEP_Payments_Table] ([col1], [col2])
output inserted.id into #ids
values ('testval1', 'testval2');
Problem
I am reluctant to add the declare and output inserted into the for loop, because I do not want it to do it for every line. I want a single id to be generated whether a user inserts 1 row of data, or 100 rows of data.
This is important as this receipt id will be used to track status of request.
Any ideas how to solve this problem?
Thanks

Related

SQL Statement to grab data from entry form to Data table in Microsoft Access 2010 VBA

So I'm setting up a database in MS Access 2010 (first time doing this). I can't seem to get the syntax of the SQL statement right. I want to take the data I have entered into a data entry form and insert a new row into a table, with that data. All of this using SQL in the VBA editor (only code I have available, all others are blocked)
Private Sub Add_Click()
Dim sSQL As String
sSQL = "INSERT INTO Data (Type, Name, Quantity, Amount, Class, Series, Client, Date1, Date2) VALUES " & _
"('" & Me!txtType & "','" & Me!txtName & "'," & Me!txtQuantity & "," & Me!txtAmount & ",'" & Me!txtClass & "','" & Me!txtSeries & "','" & Me!txtClient & "'," & Me!date1 & "," & Me!date2 & ")"
Debug.Print sSQL
CurrentDb.Execute sSQL
End Sub
So i Get the following error when i run the code, from the VBA editor :
"Run-time error '3134':
Syntax error in INSERT INTO statement."
And the printout of the SQL statement looks correct :
INSERT INTO Data (Type, Name, Quantity, Amount, Class, Series, Client, Date1, Date2)
VALUES ('Purhcase', 'TV', 500, 100, '', '', ' Bob', 05.08.2019, 05.08.2019)
Found the answer :
turns out one of the names of my data fields was a reserved word, therefore i simply put them all into [] and it solved the issue.
Thanks anyways for the help guys!

MS-Access updating first record when adding record

I'm fairly new to access but not to vba. I have a form that inserts data to a table with vba
rcrdAdd = "INSERT INTO " & timeTbl & " (ProjectNumber, AssignedTo, Task, taskStart) VALUES ('" & ProjectNumber.Value & "', '" & combobox.value & "', '" & combobox.value & "', '" & datetime.value & "');"
db.Execute rcrdAdd, dbFailOnError
When i run this it does add the record but it also updates the first record in the table with the project number associated with record it just added.
I don't know what or why. Can anyone shed any light here. I have tried to research why and can not find an answer
Your form is bound to a the table's recordsource and it looks like you've created a project number text box that is bound to the field
Then it looks like you're typing in the new project number (ProjectNumber.Value) for the Insert.
That will automatically update the current record when you leave - most likely you're opening the form to the first record in the table
Just create a new TEXTBOX that is UNBOUND - and use that in your INSERT INTO SQL instead of ProjectNumber.Value

Access query or VBA code to move data from one table to another depending on first row unique identifier

Is it possible to write a query to loop through the rows of a two column table, checking the first column for a certain identifier and copy the data in the second column into a new table?
Example:
tblSurveyData
FirstColumn Second Column
A0 John
A2 Smith
A3 05-01-1973
tblSurveyReport
FirstName MiddleName LastName DateOfBirth
John Smith 05-01-1973
Where A0 data would go to FirstName, A1 MiddleName, A2 LastName and A3 DateOfBirth. There are many more identifiers and fields but just as an example how would you do this with a query in Access or is VBA a better solution?
The only solution I came up with is the following VBA but this bypasses the two column table and tries to insert into the tblSurveyReport table. Unfortunately, it puts each piece of data into its own row which doesn't help.
If Identifier = "A0" Then
DoCmd.RunSQL "INSERT INTO tblSurveyReport " _
& "(FirstName) " _
& "VALUES ('" & Info & "')"
ElseIf Identifier = "A1" Then
DoCmd.RunSQL "INSERT INTO tblSurveyReport " _
& "(MiddleName) " _
& "VALUES ('" & Info & "')"
ElseIf Identifier = "A2" Then
DoCmd.RunSQL "INSERT INTO tblSurveyReport " _
& "(LastName) " _
& "VALUES ('" & Info & "')"
ElseIf Identifier = "A3" Then
DoCmd.RunSQL "INSERT INTO tblSurveyReport " _
& "(DateOfBirth) " _
& "VALUES ('" & Info & "')"
End If
However each piece of data is going into its own row and I need it all in the same row.
Any help is greatly appreciated.
Thanks in advance.
TC
Use INSERT INTO with a SELECT statement
INSERT INTO tblSurveyReport(FirstName) SELECT FirstName FROM tblSurveyData where FirstColumn = 'A0'
INSERT INTO tblSurveyReport(MiddleName) SELECT MiddleName FROM tblSurveyData where FirstColumn = 'A1'
You could run this using a DoCmd, as a query in Access, etc.
You will need something that would link your records together. What happens if the data gets re-sorted? How would you know that all the info in your example should be in the same record? I believe the only way to do something like this would be to create a 3rd field in your first table that determines which data belongs with which, something like a UserID. Then the table would look like this:
tblSurveyData
FirstColumn Second Column UserID
A0 John XX001
A2 Smith XX001
A3 05-01-1973 XX001
Then you could create a preliminary query like:
Select DISTINCT UserID from tblSurveyData
Use that as your "pointer" query and loop through the results, and then you can pull all the records with each UserID out and copy them into the new table. Or, you can inner join the "pointer" query and tblSurveyData, and then use a Crosstab query. The easiest way to do that would be to use the wizard to create it, and then just copy the code into your VBA.
EDIT: For easier readability for future readers, the SQL for the query you're asking for in your comment is:
SELECT Max(IIf([Identifier]="A0",[IValue],"")) AS FName, Max(IIf([Identifier]="A1",[IValue],"")) AS MName, Max(IIf([Identifier]="A2",[IValue],"")) AS LName, Max(IIf([Identifier]="A3",[IValue],"")) AS BDate FROM tblSurveyData;
You will need to change "First Column" in your sample data to "Identifier", and "Second Column" to "IValue" (or make the corresponding field name changes to the above SQL). I have tested this and it worked perfectly, giving you one record with all 4 values in corresponding fields. Once you've pasted that into a blank query, you can switch to Design View and change the query to an Append or MakeTable query and that will let you export the results to tblSurveyReport.
You could have simply two recordsets, like this:
1st recordset: rsSurveyData
2nd recordset: rsSurveyReport
The idea is to browse the first recordset along its records, and the second along its fields.
depending on the recordset object you are using (DAO or ADODB), the opening syntax will be slightly different, but you'll find all details in the help. I am using here the ADODB syntax for the 'Find', 'Move', and 'Update' methods. DAO recordsets need an extra 'Edit' method before changing the data. And I do not remember if the fields collection of the recordset object is indexed from 0 or 1 ...
Then:
rsSurveyData.moveFirst
rsSurveyReport.Find "FirstName ='" & rsSurveyData.fields("A0") & "'"
if rsSurveyReport.EOF then
'do what you have to do when the record does not exist, for example:'
rsSurveyReport.addNew
rsSurveyreport.fields(1) = rsData.fields(1)
Else
'you''ve just found the record that needs to be updated'
for i = 2 to rsSurveyData.recordcount
rsSurveyData.move i, 1
rsSurveyReport.fields(i)=rsSurveyData.fields(1)
next i
rsSurveyReport.update
Endif

T-SQL - Filtering records based on a date

I am writing SQL Server queries and need a solution for how to filter the rows that are returned properly.
The basic setup is as follows - I am selecting a bunch of records from a table based primarily on an identifier. So, for a given identifier there might be 100 records that are returned initially. Within these 100 records, however, there are a number of them that need to be deleted - not because they are duplicates, but because one is newer than the other. So I essentially just need a way to further filter the results based on whichever record was created/modified most recently.
I know that ideally, these "old" records should not be in the database, but I don't have control over that. What is happening is essentially people are updating the entries over time to reflect new information, but rather than editing the "old" entry, a new one gets entered each time. Thus, there might be 3 entries for a given identifier, but I only need the one that was most recently entered.
Is there an easy way to do this in the T-SQL query string? It would be similar to the "Last of" function in Access queries. I do have a properly formatted date column for each record.
Thanks!
My query string so far (excuse the VB syntax):
"SELECT *" & _
"FROM Performance_Override " & _
"WHERE ([Deal_Name] = " & "'" & Range("ID").value & "'" & " or" & _
" [UNIQUE_ID] LIKE " & "'" & "%SPLIT_LOAN%" & "')" & " AND" & _
" ([Scenario] = " & "'" & "BASE" & "')" & _
"ORDER BY [Date] ASC; "
Select is
select ID, max(datefield)
from table
group by ID
Do you just need a select or do you want to actually delete the old entries?
WITH TableTop AS
(
SELECT ID, User, OrderDate
ROW_NUMBER() OVER (ID BY OrderDate DESC) AS RowNumber
FROM Table
)
SELECT ID, User, OrderDate
FROM TableTop
WHERE RowNumber = 1;

insert into related tables in same time

I'm working on vb.net project. I'm using VS2010 and SQL Server 2008.
I have many tables in my database, amongst them members and bank.
members contains columns: id_member, name, mobile, tel
bank contains id_bank, name_bank
Then I created member_bank table with 2 columns: members.id and bank_id for the m:n relationship between those two tables.
How can I insert details into members and join member id directly with bank id in the member_bank table ?
I wrote this code put it doesn't work:
Dim saveok As Boolean = wnclass14.SQLExicute("Insert Into members (member_name,member_id,mobile,tel) values ('" & TextstdntName.Text & "','" & Textid.Text & "','" & TextMobile.Text & "','" & Texttel.Text & "')")
If saveok = True Then
Dim saveok1 As Boolean = wnclass14.SQLExicute("Insert Into member_bank (id_member,id_bank) values (" & ComboBoxBank.SelectedValue & ") where member_bank.id_member=members.id")
If saveok1 = True Then .......
Part of the trick here is that you kind of want all of these to take place as part of a single transaction. Thankfully, it's not that hard to do this by sending multiple statements in a single call to your "SQLExicute" function (fix your spelling please):
wnclass14.SQLExicute( _
"BEGIN TRANSACTION;" & _
"DECLARE #NewID Int;" & _
"INSERT INTO members (member_name, mobile, tel) " & _
" VALUES ('..', '555-1234', '555-5678');" & _
"SELECT #NewID = Scope_Identity();" & _
"INSERT INTO member_bank (id_member, id_bank) " & _
" VALUES (#NewID, '1234');" & _
"COMMIT;)
And while we're here, you really need to fix this function so that it's also asking for parameter data.
It is not okay to to use string concatenation to include user-entered data in your sql statements.
It is not okay to skip this because you're still learning. And
it is not okay to "just get it working" first and then go back and fix the security issues afterwards
I assume you want to return the memberid from the members table after you do an insert? If so, you need to look into SCOPE_IDENTITY(). This should return the last Identity that was inserted into the table for your scope.
Here is a good article:
http://msdn.microsoft.com/en-us/library/ms190315.aspx
I'd supply code, but I don't really understand yours.
Good luck.