String or binary data would be truncated. The statement has been terminated - sql

I always got an error when adding a new data. the error says
String or binary data would be truncated. The statement has been terminated
As I've looked back on my backend or code. It looks like there's a conflict adding a TWO LABEL DATA in one column because I would like to join the (Year)-(StudentNumber)
Here's the code of my INSERT INTO Statement
INSERT INTO
[Student_Information] (StudentID, LastName, FirstName, MiddleName, Gender,
ContactNumber, Citizenship, Religion, Birthday, Address)
VALUES
( '" & lbl_cyear.Text - studid.Text & "','" + txt_lname.Text + "', '" + txt_fname.Text + "', '" + txt_mname.Text + "', '" + DDGender.Text + "', '" & txt_cnumber.Text & "', '" & txt_citizenship.Text & "' , '" + txt_religion.Text + "' , '" & txt_bday.Text & "', '" & txt_address.Text & "' )"
and here's the code how I generate the Year and the Student Number
Sub SNYear()
Dim test As Date
test = Convert.ToDateTime(Today)
lbl_cyear.Text = test.Year
End Sub
Sub SNGenerate()
'displaying Studentid
Dim SN As Integer ' Student Number
Dim SID As String 'Student ID Num as String
Dim rdr As SqlDataReader
cmd1.Connection = cn
cmd1.Connection.Open()
cmd1.CommandText = "Select Max (StudentID) as expr1 from [Student_Information]"
rdr = cmd1.ExecuteReader
If rdr.HasRows = True Then
rdr.Read()
End If
If rdr.Item(0).ToString = Nothing Then
SN = rdr.Item(0) + 1
SID = Format(SN, "0000")
ElseIf rdr.Item(0).ToString = 0 Then
SN = rdr.Item(0) + 1
SID = Format(SN, "0000")
Else
SN = rdr.Item(0) + 1
SID = Format(SN, "0000")
End If
studid.Text = SID
cmd1.Connection.Close()
End Sub
Can someone help me with the code? How to join 2 data in different label text and save it to one column in my table.

Woah! Never ever write sql queries like that. It's subject to dangerous SQL injection, and code like that is actually used as worst-case scenarios in SQL injection lectures everywhere!
That being said, the error message String or binary data would be truncated. The statement has been terminated. actually spells out what is wrong. You are trying to insert too much data into a field that has a specific dimension.
You are trying to insert the following expression into the StudentID field:
lbl_cyear.Text - studid.Text
I'm not even sure what you want to do there. Since Visual Basic is loosely typed by default, It will probably handle the lbl_cyear.Text as a number and try to subtract the studid.Text (as a number) from it. You probably mean something like this:
lbl_cyear.Text & "-" & studid.Text
It seems you are trying to use the StudentID column for two different types of information. Don't do that. Decide on one format for the student ids and dimension the column for it.
Is this a homework assignment?

Y#atornblad has some very valid points about re-structuring your code. However, the specific problem you are asking about is likely because you are trying to insert data into a column that is longer than the column can accept.
E.g. - you are trying to insert "Lorem Ipsum" into a column that has a maximum length of 5 characters.
Edit
You need to take another look at how your table is defined and make sure it is appropriate for the data you are storing. Also - make sure the data you are trying to store is in the correct format that the table was designed for. Don't assume it's in the format you want, actually step through the program in debug mode and look at what the variable is before it gets sent to the database.

Related

Oracle to_date function with parameter doesn't work when trying to insert data

I am trying to write basic insert statement. I have columns with date type. In C# I get datetimepicker value and convert it to string, then try to insert it with to_date. But it shows ORA-01756: quoted string not properly terminated. I found question related to this error, but it is not the same with my case. What is wrong with my script:
"Insert Into Booklets (id, exam, number_of_booklets, who_gave, when_gave, return_date) values(booklet_seq.NEXTVAL, '" + exam + "', '" + bookletNumbers + "', '" + whoGaveId + "', '" + "to_date(" + gaveTime + ", 'DD/MM/YYYY'))"
As Abra mentioned, you are ending up with
values ( ...., to_date(20/01/2020,'DD/MM/YYYY'), ... )
when you need to have
values ( ...., to_date('20/01/2020','DD/MM/YYYY'), ... )
but please, please, please do not proceed with the formatting of a SQL statement in this way if this is going to be building a true application for your workplace.
Building SQL statements by concatenation is probably the number 1 way people get hacked.
Here's a video I did on this, showing that there are tools out there that can hack your application in just a few minutes the moment you head down this path
https://youtu.be/GRh800IvllY
Binding makes your SQL immune to such hacks, eg
string sql = "select department_name from departments where department_id = " +
":department_id";
OracleCommand cmd = new OracleCommand(sql, conn);
cmd.CommandType = CommandType.Text;
OracleParameter p_department_id = new OracleParameter();
p_department_id.OracleDbType = OracleDbType.Decimal;
p_department_id.Value = 20;
cmd.Parameters.Add(p_department_id);

SQL Server Join Tables By Combining 2 Columns

This sounds ridiculously easy but I've tried so many different approaches. This query is just set up weird and I'm trying to JOIN it but there's not a common column I can do that with. There is, however, a LastFirst column (consists of LastName then FirstName) written in the context of DOE, JOHN. Then on the columns I'm trying to join that with it's just FirstName (John) and LastName (Doe).
I'm actually trying to select data from 4 tables that all are returning 1 row. These 2 tables can be joined:
SELECT
RIFQuery.*,
_Employee.EmployeeLastName + ', ' + _Employee.EmployeeFirstName AS EmployeeLastFirst,
_Employee.EmployeeTitle, _Employee.Phone As EmployeePhone,
_Employee.EmailAddress As EmployeeEmailAddress
FROM
RIFQuery
INNER JOIN
_Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE
RIFQuery.Autonumber = 1
This one has nothing to join with so I'll probably union it and null remaining columns:
SELECT *
FROM tblOrganization
This is the table that contains LastName and FirstName that I'm trying to join with RIFQuery.LastFirst:
SELECT
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM
_Clients
WHERE
_Clients.LASTNAME = left(RIFQuery.LastFirst, len(RIFQuery.LastFirst)-CHARINDEX(',', REVERSE(RIFQuery.LastFirst)))
AND _Clients.FIRSTNAME = ltrim(substring(RIFQuery.LastFirst, len(RIFQuery.LastFirst)-CHARINDEX(',', REVERSE(RIFQuery.LastFirst))+2, len(RIFQuery.LastFirst)))
In that WHERE statement the code will split the LastFirst column and get the row by searching their LastName and FirstName. I'm wondering if there's a way I can write that into a JOIN? Otherwise I can probably UNION and null remaining columns but it will look very ugly.
UPDATE
I tried 2 suggestions from here and both result in a syntax error. I forgot to mention that I'm executing this code inside Microsoft Access VBA and trying to retrieve a DAO.RecordSet. I had to remove some table names in the SELECT statement to get past a syntax error from there, so maybe I should update the question to reflect MS ACCESS and not SQL Server, although only the query is the only pure Access object and the rest are linked ODBC tables to SQL Server.
UPDATE
Just one of those issues where I can't sleep until it's fixed and will obsess until it is. If I take out all _Employee references (from SELECT and JOIN statements), it wants to work but errors about too few parameters. I just now know this is related to _Employee. Getting different results from applying parentheses and just hoping I'll get lucky and hit on it.
The error is caused by this line:
INNER JOIN [_Employee] ON [_Employee].[AutoNumber] = [RIFQuery].[CreatedBy]
I get this error:
"Syntax error (missing operator) in query expression".
As seen in this screenshot:
Here's my latest query I'm playing with, minus the parentheses:
str = "SELECT [RIFQuery].*, " & vbCrLf & _
" ([_Employee].[EmployeeLastName] & ', ' & [_Employee].[EmployeeFirstName]) AS [EmployeeLastFirst], " & vbCrLf & _
" [_Employee].[EmployeeTitle], " & vbCrLf & _
" [_Employee].[Phone] AS [EmployeePhone], " & vbCrLf & _
" [_Employee].[EmailAddress] AS [EmployeeEmailAddress], " & vbCrLf & _
" [_Clients].[Gender] AS [ClientGender], " & vbCrLf & _
" [_Clients].[DOB] AS [ClientDOB], " & vbCrLf & _
" [_Clients].[SSN] AS [ClientSSN] " & vbCrLf & _
"FROM [_Clients] " & vbCrLf & _
" INNER JOIN [RIFQuery] ON [RIFQuery].[LastFirst] = [_Clients].[LASTNAME] & ', ' & [_Clients].[FIRSTNAME] " & vbCrLf & _
" INNER JOIN [_Employee] ON [_Employee].[AutoNumber] = [RIFQuery].[CreatedBy] " & vbCrLf & _
"WHERE [RIFQuery].[Autonumber] = 1;"
For debugging purposes, if I remove those last 2 lines and the _Employee SELECT statements, it'll process the query without a problem. If anyone has any ideas just let me know.
I was focused on that RIFQuery JOIN statement being the culprit for the longest time but I've found that simply is not the issue any more. With that said, this thread has been essentially solved and I appreciate the help.
MS Access is using a slightly different syntax than SQL Server when it comes to using more than one JOIN. You could leave out the JOIN with the _Clients (making it a cross join) and move that condition to the WHERE clause, which would make the query look like this (and which would allow you to display the design window for the query without any problem)
SELECT RIFQuery.*,
EmployeeLastName + ', ' + EmployeeFirstName As EmployeeLastFirst,
EmployeeTitle, Phone As EmployeePhone, EmailAddress As EmployeeEmailAddress,
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM _Clients, RIFQuery INNER JOIN _Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE RIFQuery.LastFirst = _Clients.LASTNAME & ", " & _Clients.FIRSTNAME;
Instead of assembling the query string in VBA just for being able to change the parameter value, I suggest to save the following query as an Access object (maybe qryRIF):
PARAMETERS lgRIF Long;
SELECT RIFQuery.*,
EmployeeLastName + ', ' + EmployeeFirstName As EmployeeLastFirst,
EmployeeTitle, Phone As EmployeePhone, EmailAddress As EmployeeEmailAddress,
Gender As ClientGender, DOB As ClientDOB, SSN As ClientSSN
FROM _Clients, RIFQuery INNER JOIN _Employee ON RIFQuery.CreatedBy = _Employee.AutoNumber
WHERE RIFQuery.LastFirst = _Clients.LASTNAME & ", " & _Clients.FIRSTNAME
AND RIFQuery.Autonumber = [lgRIF];
In your VBA code, you can use code like the following to grab the QueryDef object, assign the parameter value and open a recordset:
With CurrentDb.QueryDefs!qryRIF
!lgRIF = lgRIF
With .OpenRecordset()
' ... your code ...
.Close
End With
.Close
End With

SQL INSERT INTO VALUE statement using a SELECT statement with a variable

I have 2 tables:
Tbl_Task - Has all the tasks for a process (TaskNum is unique. TaskName is what i'm writing to Tbl_Proc)
Tbl_Proc - Will hold the status of each task for a customer
When a new customer is created, I'm using the forms on close event to write each task from Tbl_Task into Tbl_Proc. I'm using the customer name from the form to complete the record in the Tbl_Proc.
My thought is to use an integer to increment the TaskNum and assign that task numbers TaskName to the Tbl_Proc[ProcTaskName]. Then loop through all task numbers. As you can see, I'm stuck on the use of my integer variable.
Here is what I have. I can successfully write the Company name but I can't get the ProcTaskName:
Private Sub Form_Close()
On Error GoTo Err_Form_Close
Dim strCompany As String
Dim sqls As String
Dim x As Integer
strCompany = Me![CoName]
'MsgBox strCompany
x = 1
sqls = "INSERT INTO Tbl_Proc(ProcCo, ProcTaskName)" & _
"VALUES ('" & strCompany & "', SELECT TaskName FROM Tbl_Task WHERE TaskNum=""" & x & """)"
DoCmd.RunSQL sqls
'This works - "VALUES ('" & strCompany & "', 'cat')"
Exit_Form_Close:
Exit Sub
Err_Form_Close:
MsgBox Err.Description
Resume Exit_Form_Close
End Sub
If I understand what you are asking correctly, you want your sql to look something like this:
INSERT INTO Tbl_Proc(ProcCo, ProcTaskName)
SELECT <yourCompanyVariable>, TaskName
FROM Tbl_Task
WHERE TaskNum=<whateverItIsYouHaveHere>
The select will return all of the tasks with your given number, each marked with your company variable. All of that will be inserted into your table.
If you can define everything you want in tbl_task easily, like where defaultTasks = 1 you can insert all of the tasks you need in one query without having to loop.
Thanks for the input man of much desired pants... :)
I added another column to Tbl_Tasks [TaskDefault] and made all values 1.
The following code works within Microsoft Access 2013 VBA module.
sqls = "INSERT INTO Tbl_Proc(ProcCo, ProcTaskName)" & _
"SELECT '" & strCompany & "', TaskName " & _
"FROM Tbl_Task WHERE TaskDefault=1"
DoCmd.RunSQL sqls

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

VBA sql query problem

Below query is resulting NO rows
lstResults.RowSource = "select EmpId from tblTesting where Empid ='" & Me.txtSearchEmpId.Value & "'"
Where below working fine :
lstResults.RowSource = "select * from tblTesting"
WHere is the fault here?
I check the value of '" & Me.txtSearchEmpId.Value & "'" using break point its having the value of "123" (numerical)
My empid is numerical value
Please help
If your EmpId is numerical, you probably want to remove the single-quotes:
lstResults.RowSource = "select EmpId from tblTesting where Empid = " & Me.txtSearchEmpId.Value
How does that work?
First, remove the single quotes from around your value, if it really is a number.
Second, cleanse your input. What if someone types 123 or true into your input field? You've then let them select all inputs. You might want to convert the value to an integer and then back to a string to make sure it is pure.
See xkcd #327: