I have a simple table in a sheet (from A1 till B9)
try1 try0
try3 try3
try5 try5
try7 try7
try9 try9
try11 try11
try13 try13
try15 try15
try17 try17
I am using a script to insert the records to a mysql table.
function MysqlData() {
var conn = Jdbc.getConnection('jdbc:mysql://mysite/myddb', 'user', 'pwd');
var stmt = conn.createStatement();
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
var sql = "INSERT INTO test (field1, field2) VALUES ('" + data[i][0] + "'," + data[i][1] + ")";
var count = stmt.executeUpdate(sql,1)
}
stmt.close();
conn.close();
}
when executing this script on the page including the table, i get the error :
Unknown column 'try0' in 'field list'
What is wrong in my code?
You quoted ('') value1, but missed value2:
var sql = "INSERT INTO test (field1, field2) VALUES ('" + data[i][0] + "','" + data[i][1] + "')";
However, directly sending strings opens you up to sql injections. Use parameterized statements:
var sql = "INSERT INTO test (field1, field2) VALUES (?, ?)";
var stmt = conn.prepareStatement(sql);
for (var i = 0; i < data.length; i++) {
stmt.setString(1, data[i][0]);
stmt.setString(2, data[i][1]);
stmt.addBatch();
}
stmt.executeBatch();
References:
Jdbc write sample
Related
Right now I use this cumbersome approach when I want to add a row whose data is in a JS Object
Adding a row to a table:
const mysql = require('mysql')
var db = mysql.createConnection(DBInfo)
var databaseObj = {val1: '1', name: 'John', age: 40} // row to insert
var query = 'INSERT INTO my_table ('
var databaseKeys = Object.keys(databaseObj)
for (let i = 0; i < databaseKeys.length; i++) {
query += databaseKeys[i] + (i !== databaseKeys.length - 1 ? ', ' : ')')
}
query += ' ' + 'VALUES('
for (let i = 0; i < databaseKeys.length; i++) {
query += '\'' + databaseObj[databaseKeys[i]] + '\'' + (i !== databaseKeys.length - 1 ? ', ' : ')')
}
db.query(query, function (err, results, fields) {...
Is there any simpler or neater way to add a row into a table, where such row data is in a JS Object? The examples I see around use an array of arrays, but in my case the info is in a Object
I should use the INSERT into table SET because they are equivalent
var db = mysql.createConnection(DBInfo)
var databaseObj = {val1: '1', name: 'John', age: 40}
var query = 'INSERT INTO my_table SET ' + db.escape(databaseObj)
db.query(query, function (err, results, fields) {...
I am having the following JavaScript Procedure:
CREATE PROCEDURE ADD_OBSERVATION_VALUES()
RETURNS string
LANGUAGE JAVASCRIPT
AS
$$
arr = [];
// Get number of rows
//var query = "SELECT COUNT(*) FROM #ingest_stg/load (file_format => 'csv_format', pattern => '.*[.]csv.gz') t";
var query = "SELECT * FROM IYCF_TEMP";
var stmt = snowflake.createStatement( {sqlText: query} );
var rows_result = stmt.execute();
// rows_result.next();
// num_rows = rows_result.getColumnValue(1);
var row_num = 1;
var record_source = 'ONA'
// Set the indicators
COLUMN_FIELD_NAMES = ['beneficiary',
'nbr_1st_cons_6mc_iycfc number',
'followup_2nd_time_6mc_iycfc'];
while(rows_result.next()){
for (var col_num = 0; col_num<COLUMN_FIELD_NAMES.length; col_num = col_num+1){
var col_name = COLUMN_FIELD_NAMES[col_num];
var query = "INSERT INTO LINK_OBSERVATION_FIELD(FIELD_NAME_OBSERVATION_HASH_KEY, LOAD_DT, RECORD_SRC, OBSERVATION_DATE_LOCATION_HASH_KEY, INDICATOR_HASH_KEY)"
query += "VALUES (md5(concat(COLUMN_FIELD_NAMES[col_num], rows_result['date'])), current_timestamp(), record_source, md5(rows_result['date']), md5(COLUMN_FIELD_NAMES[col_num]))";
var stmt = snowflake.createStatement( {sqlText: query} );
if(stmt.execute()){
var query = "INSERT INTO SAT_FIELD_VALUES(OBSERVATION_FIELD_HASH_KEY, LOAD_DT, LOAD_END_DT, record_src, FIELD_VALUE, REVIEW_STATUS, SUBMISSION_DT, FIELD_NAME_OBSERVATION_HASH_KEY)"
query += "VALUES (md5(md5(concat(rows_result[col_name], rows_result['date']))),current_timestamp(), NULL, record_source, rows_result[col_name], 'PENDING', rows_result['_submission_time'], md5(concat(rows_result[col_name], rows_result['date'])))";
var stmt = snowflake.createStatement( {sqlText: query });
stmt.execute()
}
}
}
return "DONE"
$$;
It will loop over a specific field names of a survey to add them with some changes into specific tables on Snowflake.
I am keep getting the following error:
Execution error in store procedure ADD_OBSERVATION_VALUES: SQL compilation error: error line 1 at position 163 invalid identifier 'COLUMN_FIELD_NAMES' At Statement.execute, line 33 position 20
COLUMN_FIELD_NAMES seems to be a variable defined in JS:
// Set the indicators
COLUMN_FIELD_NAMES = ['beneficiary', ...
But then the code uses it as a literal string while building a query:
query += "VALUES (md5(concat(COLUMN_FIELD_NAMES[col_num], ...
Instead, it should be parsed and concatenated with JavaScript and, as in:
query += "VALUES (md5(concat(" + COLUMN_FIELD_NAMES[col_num] +", ...
If executing the query doesn't work, try printing the value instead of executing it, and then debug.
I’m trying to automate work routines with google forms, php and mysql. I did the following software architecture.
There is the form named as S, it is the static one, since I created it manually using GUI. Form Sform has the form submit trigger which puts data into the my mysql database.
After that data is processed by the php script which finally calls google script, which is published as a web application.
This script gets get parameters and parses them, gets new processed data from my database and programmatically builds forms depending on the selected data, finally it adds a trigger to dynamically (programmatically) created form or forms (let's name them as Dform).
The problem is that the function FormApp.getActiveForm() which is coded in the trigger of programmatically created form returns form id of the static form (which is manually created).
Here the code of static form Sform submit trigger:
function SaveData() {
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
var formResponse = formResponses[formResponses.length-1];
var email = formResponse.getRespondentEmail();
var itemResponses = formResponse.getItemResponses();
var workDay = null;
var workFiles = null;
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
if (itemResponse.getItem().getTitle() == 'Pick the date of files you uploading') {
workDay = itemResponse.getResponse().toString();
}
if (itemResponse.getItem().getTitle() == 'Choose log files to be uploaded') {
workFilesIds = itemResponse.getResponse();
}
}
var dbUrl = '...';
var user = '...';
var userPwd = '...';
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.prepareStatement('select worker_id from in_workers where worker_name = ?');
stmt.setString(1, email);
var results = stmt.executeQuery();
var worker_id = -1;
while (results.next()) {
worker_id = results.getString(1);
}
results.close();
if (worker_id == -1) {
stmt = conn.prepareStatement('INSERT INTO in_workers '
+ '(worker_name) values (?)', 1);
stmt.setString(1, email);
stmt.executeUpdate();
var res = stmt.getGeneratedKeys();
res.beforeFirst();
res.next();
worker_id = res.getInt(1);
}
var fName = '';
var fBlob = new Array(workFilesIds.length);
for (var j = 0; j < workFilesIds.length; j++) {
var file = DriveApp.getFileById(workFilesIds[j]);
fName = fName + '\n\r' + file.getName();
fBlob[j] = file;
stmt = conn.prepareStatement('INSERT INTO test_dep_files '
+ '(worker_id, file_name, file_date, file_body) values (?, ?, ?, ?)');
stmt.setString(1, worker_id);
stmt.setString(2, file.getName());
stmt.setDate(3, Jdbc.parseDate(workDay));
stmt.setBytes(4, file.getBlob().getBytes());
stmt.executeUpdate();
}
conn.close();
GmailApp.sendEmail('...', 'Control workplace form completed'
, 'User ' + email + ' uploaded data on ' + workDay
+ ' file list: ' + fName,
{attachments: fBlob, name: fName});
}
Here the code of script published as web application:
function doGet(e) {
var worker_id = e.parameter['worker_id'];
var form_trig_func_name = e.parameter['form_trig_func_name'];
var dbUrl = '...';
var user = '...';
var userPwd = '...';
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
stmt = conn.prepareStatement('select form_id from in_workers where worker_id = ?');
stmt.setString(1, worker_id);
var results = stmt.executeQuery();
var form_id;
results.beforeFirst();
while (results.next()) {
form_id = results.getString(1);
}
results.close();
var form;
try {
form = FormApp.openById(form_id);
var items = form.getItems();
var l = items.length;
for (var j = 0; j < l; j++) {
form.deleteItem(0);
}
} catch (e) {
form = FormApp.create('Enter additional products data');
}
stmt = conn.prepareStatement('select fc_id, fc_name_sys, fc_date from test_dep_fc t1'
+ ', test_dep_files t2 where t1.file_id = t2.file_id and fc_name_real is null '
+ 'and worker_id = ?');
stmt.setString(1, worker_id);
var results = stmt.executeQuery();
results.beforeFirst();
while (results.next()) {
form.addTextItem()
.setTitle(results.getString(2) + ' от ' + results.getString(3))
.setHelpText(results.getString(1));
}
results.close();
form_id = form.getId();
var allTriggers = ScriptApp.getUserTriggers(form);
var l = allTriggers.length;
for (var i = 0; i < l; i++)
ScriptApp.deleteTrigger(allTriggers[i]);
allTriggers = ScriptApp.getProjectTriggers();
l = allTriggers.length;
for (var i = 0; i < l; i++) {
if (allTriggers[i].getHandlerFunction() === 'saveData' + form_trig_func_name) {
ScriptApp.deleteTrigger(allTriggers[i]);
}
}
ScriptApp.newTrigger('saveData'+form_trig_func_name)
.forForm(form)
.onFormSubmit()
.create();
var form_url = form.getPublishedUrl();
stmt = conn.prepareStatement('update in_workers set form_id = ?, form_url = ? where worker_id = ?');
stmt.setString(1, form_id);
stmt.setString(2, form_url);
stmt.setString(3, worker_id);
stmt.execute();
conn.close();
return HtmlService.createHtmlOutput(form_id + '\n\r' + form_trig_func_name);
}
This is the code of dynamically (programmatically) created forms Dforms:
function saveData2() {
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
var formResponse = formResponses[formResponses.length-1];
var itemResponses = formResponse.getItemResponses();
var dbUrl = '...';
var user = '...';
var userPwd = '...';
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var fc_names_real = '';
var fc_ids = '';
var fc_names_sys = '';
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
var fc_id = itemResponse.getItem().getHelpText();
var fc_name_sys = itemResponse.getItem().getTitle();
var fc_name_real = itemResponse.getResponse().toString();
fc_names_real = fc_names_real + ' ' + fc_name_real;
fc_ids = fc_ids + ' ' + fc_id;
fc_names_sys = fc_names_sys + ' ' + fc_name_sys;
stmt = conn.prepareStatement('update test_dep_fc '
+ 'set fc_name_real = ? where '
+ 'fc_id = ?');
stmt.setString(1, fc_name_real);
stmt.setString(2, fc_id);
stmt.executeUpdate();
}
conn.close();
GmailApp.sendEmail('...', 'Control workplace form2 completed'
, 'Product serial nums: ' + fc_names_real
+ '\n\rProducts sys nums: ' + fc_names_sys
+ '\n\rProducts ids: ' + fc_ids
);
}
function saveData3() {
the same code as for saveData2
}
function saveData4() {
the same code as for saveData2
}
function saveData5() {
the same code as for saveData2
}
...
So the problem is that in saveData2 first code instruction returns wrong form id. It always returns form id of Sform.
Please help me with this, I'm ready to think that I have found a google forms bug.
Thanks a lot, Yaroslav
EDIT 1
hi #tehhowch, thank you, I did try, but, unfortunately, following code
function saveData2(e) {
//var form_id = e.source.getId();
...
returns wrong form id as well, it returns Sform id.
Finally this issue was solved next day it was written here. The solution is as simple as it is stupid one.
In the script published as web application code I add following instructions after form creation code. I save trigger function name to its properties.
PropertiesService.getDocumentProperties().setProperty(
'saveData'+form_trig_func_name, form_id);
Code to dynamically (programmatically) create forms Dforms was rewritten. When corresponding trigger fires I just take a formId in earlier saved property value.
function saveData2(e) {
//var form_id = e.source.getId();
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData2');
saveDataAll (form_id, 2);
}
function saveData3() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData3');
saveDataAll (form_id, 3);
}
function saveData4() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData4');
saveDataAll (form_id, 4);
}
function saveData5() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData5');
saveDataAll (form_id, 5);
}
function saveData6() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData6');
saveDataAll (form_id, 6);
}
function saveData7() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData7');
saveDataAll (form_id, 7);
}
function saveData8() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData8');
saveDataAll (form_id, 8);
}
function saveData9() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData9');
saveDataAll (form_id, 9);
}
function saveData10() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData10');
saveDataAll (form_id, 10);
}
function saveData11() {
var form_id = PropertiesService.getDocumentProperties().getProperty('saveData11');
saveDataAll (form_id, 11);
}
function saveDataAll (form_id, saveData)
{
var form = FormApp.openById(form_id);
...
I have not more then ten users of this functional and such workaround works for me. So the problem is closed.
I have a google apps script like the following:
// Initialize DB variables
var address = 'my-address'
var user = 'my-user-name'
var password = 'my-password'
var db = 'my-db'
var dbUrl = 'jdbc:mysql://' + address + '/' + db
function testUtf8() {
// Generate an SQL query
var conn = Jdbc.getConnection(dbUrl, user, password)
var stmt = conn.createStatement();
var results = stmt.executeQuery('SELECT * FROM my_table WHERE col_name=\'中文\';')
// Display query result
var colCount = results.getMetaData().getColumnCount()
while (results.next()) {
var colCount = results.getMetaData().getColumnCount() // No result is retured even though there is a value of `中文` in col_name.
for (var col = 0; col < colCount; col++) {
Logger.log(results.getString(col + 1))
}
}
// Clean up
stmt.close();
conn.close();
}
The SQL query fails to find the data even if I have a value of 中文 in col_name in the table.
When I change the query from SELECT * FROM my_table WHERE col_name='中文'; to SELECT * FROM my_table WHERE col_name='abc';, it successfully returns the data.
So this must be a problem of encoding.
How can I successfully execute an SQL query which contains Chinese character?
Changing
var dbUrl = 'jdbc:mysql://' + address + '/' + db to var dbUrl = 'jdbc:mysql://' + address + '/' + db
to
var dbUrl = 'jdbc:mysql://' + address + '/' + db + '?useUnicode=true&characterEncoding=UTF-8'
solves the problem.
It tells jdbc to use utf-8 encoding.
I'm trying to create a function that takes a data range/specified range in my Google spreadsheet and inserts every row that isn't blank into a MySQL table.
I want to take column range A:V in "Sheet One" and insert them to the "mysql_table" table. I'm new to using JDBC google scripts and below is what I've come up with so far, but I can't get it to work with my current knowledge.
function putData() {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
conn.setAutoCommit(false);
var ss = SpreadsheetApp.getActiveSpreadsheet(),
sheet = ss.getSheetByName("Sheet One"),
range = sheet.getDataRange(),
values = range.getValues(),
row;
var start = new Date();
function writeManyRecords() {
for (var r=1; r<values.length; r++) {
if( values[r].join('') === '' ) return 'Blank row encountered';
row = values[r];
var i = 0;
var stmt = conn.prepareStatement('INSERT INTO mysql_table '
+ '(field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19, field20, field21, field22) values (' + start + row[i] + ')');
stmt.addBatch();
var batch = stmt.executeBatch();
conn.commit();
conn.close();
var end = new Date();
}
}
}
Anyone have any ideas on how I can achieve this?
I came up with a solution and I'm posting it here for anyone else looking for a way of writing to MySQL from Google Sheets. Here's a simplified version:
function putData() {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.createStatement();
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
var sql = "INSERT INTO test (test, num) VALUES ('" + data[i][0] + "'," + data[i][1] + ")";
var count = stmt.executeUpdate(sql,1)
}
stmt.close();
conn.close();
}