Error: ER_INVALID_JSON_TEXT: Invalid JSON text: "Invalid value." at position 1 in value for column '._data'. IN NODE JS - mysql

I want to insert JOSN data/object into mysql using stored procedure using node js. First of all I know there are some similar question out there but I tried them and but still didn't get the result.
This is the first time I am using stored procedure and node js, So I have table name test_data
test_data
CREATE TABLE `test_data` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL DEFAULT NULL,
`address` VARCHAR(255) NULL DEFAULT NULL,
`city` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2
;
This is stored procedure insert_data:
insert_data
CREATE DEFINER=`root`#`localhost` PROCEDURE `insert_data`(
IN `_data` JSON
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
declare p_name varchar(255) default null;
declare p_address varchar(255) default null;
declare p_city varchar(255) default null;
set p_name= json_unquote(json_extract(_data, '$.name'));
set p_address= json_unquote(json_extract(_data, '$.address'));
set p_city= json_unquote(json_extract(_data, '$.city'));
insert into test_data(name, address, city) values(p_name, p_address, p_city);
END
here is my node js code :
const con = require('./db/connection');
const _data = {
"name": "Ironman",
"address": "ani#gamil.com",
"city": "bhilai"
}
const sql = "CALL insert_data('"+_data +"')"
con.query(sql, _data,(error, result) => {
if(error){
return console.log("There is error in the query: " + error)
}
console.log(result)
})
ERROR
There is error in the query: Error: ER_INVALID_JSON_TEXT: Invalid JSON text: "Invalid value." at position 1 in value for column '._data'.
please help me out here, what am i doing wrong ?
Thanks

It seems to me that you are not actually passing a JSON value?
const _data = {
"name": "Ironman",
"address": "ani#gamil.com",
"city": "bhilai"
};
The above is a Javascript object, not its JSON representation. So here
const sql = "CALL insert_data('"+_data +"')"
the actual value of sql will be "CALL insert_data('[object Object]')" which is in fact not valid. Try dumping sql to console to verify that this is indeed the case.
Try with:
const sql = "CALL insert_data('"+ JSON.stringify(_data) +"')"

Related

Prisma - ConnectorError

I'm trying to learn Prisma on my hobby project so I started with basics.
The first thing I tried was a simple GET request which should list all results in a table.
// Using "#prisma/client": "^3.8.1",
const position = await prisma.position.findMany();
It worked fine but obviously, I don't have any data so it return an empty array. If I try to add some items to the Position table I'm getting error (mentioned below). Same error I'm getting also from Prisma Studio so I wonder If I did something wrong or what can I do to fix it.
Prisma schema
model Position {
id Int #id #default(autoincrement())
name String #db.VarChar(255)
externalId String #db.VarChar(255)
benefits String #db.Text()
}
MySQL Schema
CREATE TABLE `Position` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`externalId` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`benefits` text COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Query:
await prisma.position.create({
data: {
name: 'Position Name',
externalId: '321',
benefits: 'My benefits',
},
});
Error:
Error occurred during query execution:
ConnectorError(ConnectorError { user_facing_error: None, kind: QueryError(Server(ServerError { code: 1064, message: "target: referral.-.primary: vttablet: (errno 1064) (sqlstate 42000) (CallerID: unsecure_grpc_client): Sql: \"insert into Position(`name`, externalId,
benefits) values (:v1, :v2, :v3)\", BindVars: {}", state: "42000" })) })
at cb (C:\Develop\referral-nextjs-prisma\node_modules\#prisma\client\runtime\index.js:38695:17)
at async assetHandler (webpack-internal:///./pages/api/position/index.tsx:12:34)
at async Object.apiResolver (C:\Develop\referral-nextjs-prisma\node_modules\next\dist\server\api-utils.js:102:9)
at async DevServer.handleApiRequest (C:\Develop\referral-nextjs-prisma\node_modules\next\dist\server\base-server.js:1076:9)
at async Object.fn (C:\Develop\referral-nextjs-prisma\node_modules\next\dist\server\base-server.js:963:37)
at async Router.execute (C:\Develop\referral-nextjs-prisma\node_modules\next\dist\server\router.js:222:32)
at async DevServer.run (C:\Develop\referral-nextjs-prisma\node_modules\next\dist\server\base-server.js:1103:29)
at async DevServer.run (C:\Develop\referral-nextjs-prisma\node_modules\next\dist\server\dev\next-dev-server.js:444:20)
at async DevServer.handleRequest (C:\Develop\referral-nextjs-prisma\node_modules\next\dist\server\base-server.js:319:20) {
clientVersion: '3.8.1'
}

Unable to enter null value in bigint or double datatype in mariadb table using python

I am inserting records in maria db table from a file using python. Input file has header. Population and Avg_Height columns in the file are partial empty. I want it to go as null value in table as well. Population column in table is set as bigint(20) and can accept null value. I am trying the below code -
Table Definition -
CREATE TABLE `local_db`.`table_x` (
`Unique_code` varchar(50) NOT NULL,
`city` varchar(200) DEFAULT NULL,
`state` varchar(50) DEFAULT NULL,
`population` bigint(20) DEFAULT NULL,
`Avg_Height` double DEFAULT NULL,
`Govt` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
try:
connection = mysql.connector.connect(host='localhost',
database='local_db',
user='root',
password='root',
port = '3306')
input_file = "input_file"
csv_data = csv.reader(open(input_file))
next(csv_data)
cursor = connection.cursor()
for row in csv_data:
cursor.execute("""
INSERT INTO table_x(Unique_code,city,state,population,Avg_Height,Govt)
VALUES(%s,%s,%s,%s,%s,%s)
ON DUPLICATE KEY UPDATE city = VALUES(city),state = VALUES(state), \
population = VALUES(population),Avg_Height = VALUES(Avg_Height),Govt = VALUES(Govt)""")
connection.commit()
print(cursor.rowcount, "Record inserted successfully into table_x")
cursor.close()
except mysql.connector.Error as error:
print("Failed to insert record into table_x table {}".format(error))
finally:
if (connection.is_connected()):
connection.close()
print("MySQL connection is closed")
But I am getting below error -
Failed to insert record into table_x table 1366 (22007): Incorrect integer value: '' for column `local_db`.`table_x`.`population` at row 1
MySQL connection is closed
Please suggest what code changes I can do here to handle this situation.
You need to insert null instead of '' empty string. here is the demo.
CREATE TABLE `table_x` (
`Unique_code` varchar(50) NOT NULL,
`city` varchar(200) DEFAULT NULL,
`state` varchar(50) DEFAULT NULL,
`population` bigint(20) DEFAULT NULL,
`Avg_Height` double DEFAULT NULL,
`Govt` varchar(50) DEFAULT NULL
) ;
INSERT INTO table_x(Unique_code,city,state,population,Avg_Height,Govt)
values
('xyz','abc','dd',null ,3, 'fd');
You need to insert NULL in that situation instead of an empty string. You can pre-process the row list to convert empty strings into None, which will have the same effect:
for row in csv_data:
row = [None if v == '' else v for v in row]
# write to table

Stored Procedure for update not working

I am new to writing stored procedures, and i have some issues executing this one.it is able to update the name and address but is not able to update the employeecount.And i am not able to track the error i have made.
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_update_company_details`(
IN p_id int(11),
IN p_name varchar(45),
IN p_address varchar(45),
IN p_num_employee int(11)
)
BEGIN
UPDATE company
SET name=p_name,
address=p_address,
employeecount=p_num_employee
WHERE id=p_id;
END
And this the table in the database
CREATE TABLE `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`address` varchar(45) DEFAULT NULL,
`employeecount` int(11) DEFAULT NULL,
`logo` blob,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
A std table,not anything fancy.
And this is how iam calling this stored procedure.
MySqlCommand cmd = new MySqlCommand(String.Format("call sp_update_company_details({0},'{1}','{2}',{3})",
id,request.Name,request.Address,request.NumberOfEmployees), conn);
id and request are passed as parameter to the function where this call is made.
This is almost certainly an issue with your calling code not the stored procedure. If you try executing it from workbench, it should succeed without any issues.
To clean-up and fix your code, you really should make your call (all of your calls and queries) paramaterized like so:
using (var conn = new MySqlConnection("connString"))
{
using (var cmd = new MySqlCommand("sp_update_company_details"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("p_id", id);
cmd.Parameters.AddWithValue("p_name", request.Name);
cmd.Parameters.AddWithValue("p_address", request.Address);
cmd.Parameters.AddWithValue("p_num_employee", request.NumberOfEmployees);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
I would also do a step through to ensure that the values you think are being passed by request are actually the values you think they are.

MySqlHelper not pushing through query parameters to MySQL

I have a WPF/.Net 4.5 C# app, and I'm using MySQL NET Connector 6.8.3. I'm trying to execute a stored proc in a MySQL database, that expects 3 parameters.
The table is as follows:
CREATE TABLE `geofences` (
`id_geofences` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`description` varchar(255) DEFAULT NULL,
`type_id` int(11) NOT NULL,
`shape_id` int(11) NOT NULL,
PRIMARY KEY (`id_geofences`),
UNIQUE KEY `id_geofences_UNIQUE` (`id_geofences`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The stored proc is as follows:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `insert_geofence`(geofenceName VARCHAR(45), geofenceDescription VARCHAR(255), typeId INT, shapeId INT)
BEGIN
INSERT INTO geofences (`name`, `description`, `type_id`, `shape_id`) VALUES (#geofenceName, #geofenceDescription, #typeId, #shapeId);
END
This is my C# code:
string sql = "call insert_geofence (#geofenceName, #geofenceDescription, #typeId, #shapeId);";
MySqlParameter[] parameters = new MySqlParameter[4];
parameters[0] = new MySqlParameter("#geofenceName", "test name");
parameters[1] = new MySqlParameter("#geofenceDescription", "test description");
parameters[2] = new MySqlParameter("#typeId", 1);
parameters[3] = new MySqlParameter("#shapeId", 2);
MySql.Data.MySqlClient.MySqlHelper.ExecuteNonQuery(ConnectionString, sql, parameters);
But I'm getting the following error:
"Column 'name' cannot be null"
I have made column name a NOT NULL column. So it appears the values of the parameters are not being sent through to the stored procedure. Indeed, if I remove the NOT NULL restriction from the name column, the query executes, but all four columns are NULL.
I can't figure out where I'm going wrong. Any ideas? Thanks...
I have tried a similar code to yours and it works as expected after some little changes
First the SP is like this:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_test`(n varchar(10), f varchar(255))
BEGIN
INSERT INTO filename (username, file) VALUES (n, f);
END
Now the call to the SP is like this
string conn = "Server=localhost;Database=test;Uid=root;Pwd=root;Port=3306";
string cmdText = "call sp_test(#n, #f);";
MySqlParameter[] parameters = new MySqlParameter[2];
parameters[0] = new MySqlParameter("#n", "steve");
parameters[1] = new MySqlParameter("#f", #"d:\temp\test.txt");
MySql.Data.MySqlClient.MySqlHelper.ExecuteNonQuery(conn, cmdText, parameters);
It is important that you use the same name without the prefix for the parameters' name and for the placeholders in the Sql Statement. Instead it seems that the # prefix is required in the C# code

Error Delphi / MySQL / Parameters

Well, the situation is: I have 1 TComboBox called cboTipDocIden and 1 TEdit called txtDocIdenSolic.
The values of cboTipDocIden are: "1.DNI","2.RUC".
The component TUniQuery is called q_DetSolicitante.
The SQL Sentence target is:
SELECT oper_solicitante.id_solicitante, oper_solicitante.ape_pat, oper_solicitante.ape_mat,
oper_solicitante.nombre, oper_solicitante.direcc_idtipcalle, oper_solicitante.direcc_nombrecalle,
oper_solicitante.direcc_nro, oper_solicitante.idvinculo_fk
FROM oper_solicitante
WHERE oper_solicitante.tipDocIden = :TipDocIden AND
oper_solicitante.nroDocIden = :NroDocIden
The SQL is executed on OnExit event of txtDocIdenSolic, here the code:
procedure TForm1.txtDocIdenSolicExit(Sender: TObject);
var
TipDocIden, NroDocIden:string;
begin
if(length(txtDocIdenSolic.Text)>0) then
begin
TipDocIden:=chr(39)+copy(cboTipDocIden.Text,1,1)+chr(39);
NroDocIden:=chr(39)+trim(txtDocIdenSolic.Text)+chr(39);
q_DetSolicitante.Close;
q_DetSolicitante.Params[0].AsString:=TipDocIden;
q_DetSolicitante.Params[1].AsString:=NroDocIden;
q_DetSolicitante.Open;
if(length(q_DetSolicitante.FieldByName('id_solicitante').AsString)=0) then
begin
stbar.Panels[0].text:='Nuevo Solicitante...';
txtApePat.SetFocus;
end
else
begin
stbar.Panels[0].Text:='Solicitante Reiterativo...';
txtApePat.Text:=q_DetSolicitante.FieldByName('ape_pat').AsString;
txtApeMat.Text:=q_DetSolicitante.FieldByName('ape_mat').AsString;
txtNombre.Text:=q_DetSolicitante.FieldByName('nombre').AsString;
end;
end
else
msg1.Execute;
end;
Finally, the table structure is:
CREATE TABLE `oper_solicitante` (
`id_solicitante` int(11) NOT NULL,
`tipDocIden` char(1) NOT NULL,
`nroDocIden` varchar(11) NOT NULL,
`ape_pat` varchar(50) NOT NULL,
`ape_mat` varchar(50) NOT NULL,
`nombre` varchar(50) NOT NULL,
`direcc_idtipcalle` int(11) NOT NULL,
`direcc_nombrecalle` varchar(80) NOT NULL,
`direcc_nro` varchar(15) NOT NULL,
`idvinculo_fk` int(11) NOT NULL,
PRIMARY KEY (`id_solicitante`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Well, the SQL returns zero rows inside Delphi but when i change the parameters for literal values the SQL works.
Thanks for your useful help.
Remove the chr(39) characters around your parameter values. Using Params[].AsString allows the database driver to properly quote them, and you're adding (doubling) them and thus causing the query to fail.
TipDocIden:= copy(cboTipDocIden.Text,1,1);
NroDocIden:= trim(txtDocIdenSolic.Text);
q_DetSolicitante.Close;
q_DetSolicitante.Params[0].AsString := TipDocIden;
q_DetSolicitante.Params[1].AsString := NroDocIden;
q_DetSolicitante.Open;