Error when inserting a value containing an apostrophe - sql-server

I'am very new with text datatype in SQL Server 2008
I created table:
CREATE TABLE sample(id int identity,name varchar(20),Yell_Your_self text)
but I am facing problem with inserting
insert into sample values('ganesh','welcome to india')
insert into sample values('ganesh','welcome to india's largest temple')
First statement is working fine but how to execute second statement?

Try this one -
IF OBJECT_ID(N'dbo.sample') IS NOT NULL
DROP TABLE dbo.[sample]
CREATE TABLE dbo.[sample]
(
id INT IDENTITY(1,1) PRIMARY KEY
, name VARCHAR(20)
, Yell_Your_self VARCHAR(2000)
)
INSERT INTO dbo.[sample]
VALUES
('ganesh', 'welcome to india'),
('ganesh', 'welcome to india''s largest temple')
Update3:
public int get(string val1,string val2)
{
using(SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
int i = 0;
using (SqlCommand cmd = new SqlCommand("INSERT INTO dbo.sample (name, Yell_Your_self) VALUES(#val1, #val2)", con))
{
cmd.Parameters.AddWithValue("#val1", val1);
cmd.Parameters.AddWithValue("#val2", val2);
i = cmd.ExecuteNonQuery();
}
con.Close();
return i;
}
}

Likely throwing an error on the apostrophe in the india's
insert into sample values('ganesh','welcome to india''s largest temple')

The issue is that you have a single quote in the string, and a single quote is a string delimiter in SQL.
Try:
INSERT INTO sample VALUES ('ganesh','welcome to india''s largest temple')

As you are already aware that the trouble SQL is facing is to escape an apostrophy in query, which is fixed i guess. To answer your second question about how to pass value from front end like C#, parametrized query is one of the good approach. As an alternative you can go with this one also which involves string manipulations to prepare a query:
public int get(string val1,string val2)
{
string temp = string.Concat(val1,"," + val2); // concatenate all your params
temp = temp.replace("'","''").replace(",","','"); // replace any single qoute with escaped single quote
string s="insert into sample values('" + temp + "')"; // append altered string in query
SqlCommand cmd = new SqlCommand(s,con);
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
return i;
}
Hope it helps!

try this with passing dynamic value
insert into sample values(#name, N''' + #Yell_Your_self text + ''' )

Related

Violation of PRIMARY KEY constraint. Cannot insert duplicate key in object

I inherited a project and I'm running into a SQL error that I'm not sure how to fix.
On an eCommerce site, the code is inserting order shipping info into another database table.
Here's the code that is inserting the info into the table:
string sql = "INSERT INTO AC_Shipping_Addresses
(pk_OrderID, FullName, Company, Address1, Address2, City, Province, PostalCode, CountryCode, Phone, Email, ShipMethod, Charge_Freight, Charge_Subtotal)
VALUES (" + _Order.OrderNumber;
sql += ", '" + _Order.Shipments[0].ShipToFullName.Replace("'", "''") + "'";
if (_Order.Shipments[0].ShipToCompany == "")
{
sql += ", '" + _Order.Shipments[0].ShipToFullName.Replace("'", "''") + "'";
}
else
{
sql += ", '" + _Order.Shipments[0].ShipToCompany.Replace("'", "''") + "'";
}
sql += ", '" + _Order.Shipments[0].Address.Address1.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.Address2.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.City.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.Province.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.PostalCode.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.Country.Name.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.Phone.Replace("'", "''") + "'";
if (_Order.Shipments[0].ShipToEmail == "")
{
sql += ",'" + _Order.BillToEmail.Replace("'", "''") + "'";
}
else
{
sql += ",'" + _Order.Shipments[0].ShipToEmail.Replace("'", "''") + "'";
}
sql += ", '" + _Order.Shipments[0].ShipMethod.Name.Replace("'", "''") + "'";
sql += ", " + shippingAmount;
sql += ", " + _Order.ProductSubtotal.ToString() + ")";
bll.dbUpdate(sql);
It is working correctly, but it is also outputting the following SQL error:
Violation of PRIMARY KEY constraint 'PK_AC_Shipping_Addresses'. Cannot insert
duplicate key in object 'dbo.AC_Shipping_Addresses'. The duplicate key value
is (165863).
From reading similar questions, it seems that I should declare the ID in the statement.
Is that correct? How would I adjust the code to fix this issue?
I was getting the same error on a restored database when I tried to insert a new record using the EntityFramework. It turned out that the Indentity/Seed was screwing things up.
Using a reseed command fixed it.
DBCC CHECKIDENT ('[Prices]', RESEED, 4747030);GO
I'm pretty sure pk_OrderID is the PK of AC_Shipping_Addresses
And you are trying to insert a duplicate via the _Order.OrderNumber?
Do a
select * from AC_Shipping_Addresses where pk_OrderID = 165863;
or select count(*) ....
Pretty sure you will get a row returned.
It is telling you that you are already using pk_OrderID = 165863 and cannot have another row with that value.
if you want to not insert if there is a row
insert into table (pk, value)
select 11 as pk, 'val' as value
where not exists (select 1 from table where pk = 11)
What is the value you're passing to the primary key (presumably "pk_OrderID")? You can set it up to auto increment, and then there should never be a problem with duplicating the value - the DB will take care of that. If you need to specify a value yourself, you'll need to write code to determine what the max value for that field is, and then increment that.
If you have a column named "ID" or such that is not shown in the query, that's fine as long as it is set up to autoincrement - but it's probably not, or you shouldn't get that err msg. Also, you would be better off writing an easier-on-the-eye query and using params. As the lad of nine years hence inferred, you're leaving your database open to SQL injection attacks if you simply plop in user-entered values. For example, you could have a method like this:
internal static int GetItemIDForUnitAndItemCode(string qry, string unit, string itemCode)
{
int itemId;
using (SqlConnection sqlConn = new SqlConnection(ReportRunnerConstsAndUtils.CPSConnStr))
{
using (SqlCommand cmd = new SqlCommand(qry, sqlConn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#Unit", SqlDbType.VarChar, 25).Value = unit;
cmd.Parameters.Add("#ItemCode", SqlDbType.VarChar, 25).Value = itemCode;
sqlConn.Open();
itemId = Convert.ToInt32(cmd.ExecuteScalar());
}
}
return itemId;
}
...that is called like so:
int itemId = SQLDBHelper.GetItemIDForUnitAndItemCode(GetItemIDForUnitAndItemCodeQuery, _unit, itemCode);
You don't have to, but I store the query separately:
public static readonly String GetItemIDForUnitAndItemCodeQuery = "SELECT PoisonToe FROM Platypi WHERE Unit = #Unit AND ItemCode = #ItemCode";
You can verify that you're not about to insert an already-existing value by (pseudocode):
bool alreadyExists = IDAlreadyExists(query, value) > 0;
The query is something like "SELECT COUNT FROM TABLE WHERE BLA = #CANDIDATEIDVAL" and the value is the ID you're potentially about to insert:
if (alreadyExists) // keep inc'ing and checking until false, then use that id value
Justin wants to know if this will work:
string exists = "SELECT 1 from AC_Shipping_Addresses where pk_OrderID = " _Order.OrderNumber; if (exists > 0)...
What seems would work to me is:
string existsQuery = string.format("SELECT 1 from AC_Shipping_Addresses where pk_OrderID = {0}", _Order.OrderNumber);
// Or, better yet:
string existsQuery = "SELECT COUNT(*) from AC_Shipping_Addresses where pk_OrderID = #OrderNumber";
// Now run that query after applying a value to the OrderNumber query param (use code similar to that above); then, if the result is > 0, there is such a record.
To prevent inserting a record that exist already. I'd check if the ID value exists in the database. For the example of a Table created with an IDENTITY PRIMARY KEY:
CREATE TABLE [dbo].[Persons] (
ID INT IDENTITY(1,1) PRIMARY KEY,
LastName VARCHAR(40) NOT NULL,
FirstName VARCHAR(40)
);
When JANE DOE and JOE BROWN already exist in the database.
SET IDENTITY_INSERT [dbo].[Persons] OFF;
INSERT INTO [dbo].[Persons] (FirstName,LastName)
VALUES ('JANE','DOE');
INSERT INTO Persons (FirstName,LastName)
VALUES ('JOE','BROWN');
DATABASE OUTPUT of TABLE [dbo].[Persons] will be:
ID LastName FirstName
1 DOE Jane
2 BROWN JOE
I'd check if i should update an existing record or insert a new one. As the following JAVA example:
int NewID = 1;
boolean IdAlreadyExist = false;
// Using SQL database connection
// STEP 1: Set property
System.setProperty("java.net.preferIPv4Stack", "true");
// STEP 2: Register JDBC driver
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
// STEP 3: Open a connection
try (Connection conn1 = DriverManager.getConnection(DB_URL, USER,pwd) {
conn1.setAutoCommit(true);
String Select = "select * from Persons where ID = " + ID;
Statement st1 = conn1.createStatement();
ResultSet rs1 = st1.executeQuery(Select);
// iterate through the java resultset
while (rs1.next()) {
int ID = rs1.getInt("ID");
if (NewID==ID) {
IdAlreadyExist = true;
}
}
conn1.close();
} catch (SQLException e1) {
System.out.println(e1);
}
if (IdAlreadyExist==false) {
//Insert new record code here
} else {
//Update existing record code here
}
Not OP's answer but as this was the first question that popped up for me in google, Id also like to add that users searching for this might need to reseed their table, which was the case for me
DBCC CHECKIDENT(tablename)
There could be several things causing this and it somewhat depends on what you have set up in your database.
First, you could be using a PK in the table that is also an FK to another table making the relationship 1-1. IN this case you may need to do an update rather than an insert. If you really can have only one address record for an order this may be what is happening.
Next you could be using some sort of manual process to determine the id ahead of time. The trouble with those manual processes is that they can create race conditions where two records gab the same last id and increment it by one and then the second one can;t insert.
Third, you query as it is sent to the database may be creating two records. To determine if this is the case, Run Profiler to see exactly what SQL code you are sending and if ti is a select instead of a values clause, then run the select and see if you have due to the joins gotten some records to be duplicated. IN any even when you are creating code on the fly like this the first troubleshooting step is ALWAYS to run Profiler and see if what got sent was what you expected to be sent.
Make sure if your table doesn't already have rows whose Primary Key values are same as the the Primary Key Id in your Query.

How to check that any particular record already exist in the database or not before inserting record in MVC?

I am using the following code to export data from excel to Sql server database. What is going on with this code is, its importing complete data into the database.
[HttpPost]
public ActionResult Importexcel()
{
if (Request.Files["FileUpload1"].ContentLength > 0)
{
string extension = System.IO.Path.GetExtension(Request.Files["FileUpload1"].FileName);
string path1 = string.Format("{0}/{1}", Server.MapPath("~/Content/UploadedFolder"), Request.Files["FileUpload1"].FileName);
if (System.IO.File.Exists(path1))
System.IO.File.Delete(path1);
Request.Files["FileUpload1"].SaveAs(path1);
string sqlConnectionString = #"Data Source=xyz-101\SQLEXPRESS;Database=PracDB;Trusted_Connection=true;Persist Security Info=True";
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path1 + ";Extended Properties=Excel 12.0;Persist Security Info=False";
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
OleDbCommand cmd = new OleDbCommand("Select [ID],[Name],[Designation] from [Sheet1$]", excelConnection);
excelConnection.Open();
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(sqlConnectionString);
sqlBulk.DestinationTableName = "Excel_Table";
sqlBulk.WriteToServer(dReader);
excelConnection.Close();
}
return RedirectToAction("Index");
}
How to check that any particular record already exist in the database or not. If not then Insert the record into the databse else it should not.
Thanks in Advance !
Since your target is SQL Server, you can use this to your advantage.
What I would do is read the data from the excel into a DataTable (instead of using a DataReader you can use a DataAdapter), Send that DataTable to a stored procedure in the SQL server, and handle the insert there. In order to sand a data table to a stored procedure you first need to create a Table-value user defined type in your sql server, like this:
CREATE TYPE MyType AS TABLE
(
Id int,
Name varchar(20), -- use whatever length best fitted to your data
Designation varchar(max) -- use whatever length best fitted to your data
)
Then you can write a simple stored procedure with an argument of this type:
CREATE PROCEDURE InsertDataFromExcel
(
#ExcelData dbo.MyType readonly -- Note: readonly is a required!
)
AS
INSERT INTO MyTable(Id, Name, Designation)
SELECT a.Id, a.Name, a.Designation
FROM #ExcelData a LEFT JOIN
MyTable b ON(a.Id = b.Id)
WHERE b.Id IS NULL -- this condition with the left join ensures you only select records that has different id values then the records already in your database
in order to send this parameter to the stored procedure from your c# code you will have to use a SqlCommand object and add the DataTable as a parameter, something like this:
using(SqlConnection Con = new SqlConnection(sqlConnectionString))
{
using(SqlCommand InsertCommand = new SqlCommand("InsertDataFromExcel", Con))
{
SqlParameter MyParam = new SqlParameter("#ExcelData", SqlDBType.Structured);
MyParam.Value = MyDataTable; // this is the data table from the
InsertCommand.Parameters.Add(MyParam);
Con.Open();
InsertCommand.ExecuteNoQuery();
Con.Close();
}
}
Note: Code was writen directly here, some errors might be found.

Sybase BulkCopy WriteToServer error: Incorrect syntax near ','

Is it possible to populate a temp table using AseBulkCopy.WriteToServer?
I am calling the below method twice in my test app: firstly with a non-temp table and secondly with a temp table. The code runs fine with the non-temp table, but when trying to populate a temp table the error:
Incorrect syntax near ','.
is raised.
In both cases the target and source tables have just a single column, defined as an INT with the same name.
I have tried using a DataTable and an IDataReader as the source of the data and both result in the same error being raised.
I have tried using both "EnableBulkLoad=1" and "EnableBulkLoad=2" in the connection string.
I have tried using both the raw temp table name and the name prefixed with "dbo."
The data to be loaded is a single int value (ie, 1 row, 1 column) although it also happens if have longer rows or multiple rows.
It's worth noting that I can insert data into the temp table (using AseCommand.ExecuteNonQuery) and can execute a 'SELECT COUNT (1)' from the temp table (using AseCommand.ExecuteScalar) successfully.
Here is the code:
private static void BulkCopyInsertIntoTable(string tableName)
{
IDataReader dataSource = null;
SqlConnection sourceConnection = null;
MssqlCommand.GetDataReader(SqlServerConnectionString, out sourceConnection, out dataSource);
AseConnection targetConnection = new AseConnection(SybaseConnectionString);
try
{
targetConnection.Open();
AseCommand cmd = new AseCommand();
AseBulkCopy blk = new AseBulkCopy(targetConnection);
blk.DestinationTableName = tableName;
//blk.ColumnMappings.Clear();
//blk.ColumnMappings.Add(new AseBulkCopyColumnMapping(0, 0));//Doesn't make any difference with a datasource, causes an error to be raised with a datatable.
Console.WriteLine("bulkcopy insert into the table " + tableName + " ..starting: datasource");
//blk.WriteToServer(dataSource);
Console.WriteLine("bulkcopy insert into the table " + tableName + " ..starting: datatable");
blk.ColumnMappings.Clear();
DataTable dt = SybaseCommand.GetFakeDataTable(); ;
blk.WriteToServer(dt);
}
catch (AseException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
targetConnection.Dispose();
Console.WriteLine("bulkcopy insert into the table " + tableName + " ..ended");
}
}
Firstly, is it possible to populate a temp table using WriteToServer?
Assuming it is, what might I being doing wrong?
UPDATE:
When I change the line
blk.DestinationTableName = tableName;
to
blk.DestinationTableName = "XXXX";
I get the same error, so are there rules about how the temp table is named when using WriteToServer? The value of tableName is what I was using for the direct INSERT and SELECT COUNT(1) queries so I expected it to be correct.
Thanks
In my experience, the answer is no, you can't use AseBulkCopy.WriteToServer to populate a temporary table.

How to save byte[] using a procedure?

This stored procedure does not save the data, it seems to be a problem with the VARBINARY. I am passing a byte[] to it, but then it doesn't work. If I send this parameter as NULL it works.
I'm calling the procedure with the following code:
public Community AddCommunity(string name, string description, byte[] picture, User owner, int? venue, int communityID)
{
using (var database = new Database())
{
return database.Scope.GetSqlQuery<Community>("QP_AddCommunity ?, ?, ?, ?, ?, ?", "VARCHAR Name, VARCHAR Description, VARBINARY Picture, INTEGER Owner, INTEGER Venue, INTEGER ID").GetResult(name, description, picture, owner.ID, venue, communityID);
}
}
The procedure is the following:
CREATE PROCEDURE [dbo].[QP_AddCommunity]
#Name VARCHAR(120),
#Description VARCHAR(MAX),
#Picture VARBINARY(MAX),
#Owner INTEGER,
#Venue INTEGER,
#ID INTEGER
AS
BEGIN
SET NOCOUNT ON;
IF(SELECT COUNT(*) FROM QT_Community WHERE ID = #ID) = 0
INSERT INTO QT_Community(Name, [Description], Picture, [Owner], Venue) VALUES(#Name, #Description, #Picture, #Owner, #Venue);
ELSE
UPDATE QT_Community SET Name = #Name, [Description] = #Description, Picture = #Picture, [Owner] = #Owner, Venue = #Venue WHERE ID = #ID;
SELECT * FROM QT_Community WHERE ID = ##IDENTITY;
END
What's wrong with this code? Isn't VARBINARY a byte[] ?
This code works when executing on SQL Server Management Studio.
DECLARE #X varbinary(20)
Set #X = CAST('Testing' As varbinary(20))
EXECUTE [QP_AddCommunity] 'aaaaa', 'descricao', #X, 216, NULL, 0;
But when calling from the GetSqlQuery method with something on the byte[] the transaction says it's not active and not dirty. BUT if the byte[] is null it works as it should.
i found that it is impossible as this answer shows
Hello gaurav, currently our
GetSqlQuery method cannot operate
properly with parameters of type
LongVarBinary or VarBinary, thus
making it impossible for the stored
procedure to work as expected. We are
aware of this problem and we are
working on fixing it. As a work around
you should try and use Linq to achieve
your goal. Greetings, Petar the
Telerik team
Accordingly to this table it seems either BLOB, BINARY, VARBINARY would be valid types for [] of primitive type.
You could try to ask on their forums, maybe someone will be able to help you.
Try using the .WRITE method. On your INSERT, insert 0x for Picture, then update independently.
UPDATE QT_Community
SET Picture.Write (#Picture, 0, DATALENGTH(Picture))
WHERE ID = #ID
Example (Ado.Net):
byte[] ba = UlongsToBytes(ul);
try
{
string source = #"packet size=4096;integrated security=SSPI;data source=MyPC\MyNamedInstance;persist security info=False;initial catalog=Sandbox";
SqlConnection conn = new SqlConnection(source);
conn.Open();
SqlCommand a = new SqlCommand("INSERT BigintsTarget(bi) SELECT * FROM dbo.ParseImageIntoBIGINTs(#BIGINTs)", conn);
a.CommandType = System.Data.CommandType.Text;
a.Parameters.Add(new SqlParameter("#BIGINTs", System.Data.SqlDbType.Image,2147483647));
for(int q=0; q<10; q++)
{
a.Parameters[0].Value = ba;
int res = a.ExecuteNonQuery();
}
d2 = DateTime.Now;
SqlCommand b = new SqlCommand("INSERT BigintsTarget1(bi) SELECT * FROM dbo.ParseVarcharMAXIntoBIGINTs(#BIGINTs)", conn);
b.CommandType = System.Data.CommandType.Text;
b.Parameters.Add(new SqlParameter("#BIGINTs", System.Data.SqlDbType.VarChar,2147483647));
for(int q=0; q<10; q++)
{
b.Parameters[0].Value = sss;
int res = b.ExecuteNonQuery();
}
//b.ExecuteNonQuery();
conn.Close();
}
catch(Exception ex)
{
string s = ex.Message;
int t=0;
t++;
}
}

Incorrect syntax near stored procedure error

I'm updating a long list of records. In my code, everything run as predicted until it execute the query. I get an
Incorrect syntax near 'TempUpdatePhysicalCityStateZip'
(my stored procedure name). I've tested it with SQL Server Management Studio and it runs fine. So, I'm not quite sure where I got it wrong. Below is my stored procedure and code:
ALTER PROCEDURE [dbo].[TempUpdateCityStateZip]
#StoreNo nvarchar (11),
#City nvarchar(50),
#State nvarchar(2),
#Zip nvarchar(5)
AS
BEGIN
SET NOCOUNT ON;
UPDATE StoreContact
SET City = #City, State = #State, Zip = #Zip
WHERE StoreNo = #StoreNo
END
Here is my code:
Dictionary<string, string> CityStateZipList = getCityStateZipList(dbPath);
using (SqlConnection conn = new SqlConnection(dbPath))
{
conn.Open();
SqlCommand cmdUpdate = new SqlCommand("TempUpdateCityStateZip", conn);
foreach (KeyValuePair<string, string> frKeyValue in CityStateZipList)
{
cmdUpdate.Parameters.Clear();
string[] strCityStateZip = frKeyValue.Value.Split(' ');
cmdUpdate.Parameters.AddWithValue("StoreNo", frKeyValue.Key.ToString());
foreach (String i in strCityStateZip)
{
double zipCode;
if (i.Length == 2)
{
cmdUpdate.Parameters.AddWithValue("State", i);
}
else if (i.Length == 5 && double.TryParse(i, out zipCode))
{
cmdUpdate.Parameters.AddWithValue("Zip", i);
}
else
{
cmdUpdate.Parameters.AddWithValue("City", i);
}
}
cmdUpdate.ExecuteNonQuery();
}
}
I believe you can get that puzzling error message if you don't specify the command type:
cmdUpdate.CommandType = CommandType.StoredProcedure;
Don't you need the # sign before the parameter?
cmdUpdate.Parameters.AddWithValue("#State", i);
FWIW, Thats kind of a dirty piece of code there, you will probably have many issues trying to maintain that. For performance reasons you may want to parse out the CityStateZipList before you open the connection, that way you aren't keeping it open longer than you need.

Resources