05.04.2019, 02:33
|
Аспирант
|
|
Регистрация: 03.01.2018
Сообщений: 38
|
|
Структуру в SQL
Приветствую!
Есть объект
const obj = {
id: 1,
firstName: 'Вася',
birthday: Date()
}
Полей в структуре может быть больше, так как она динамическая.
Нужно преобразовать эту структуру в запрос вида:
const str = `UPDATE users SET id =1, firstName ='Вася', birthday = '1982-02-31' WHERE id =${obj.id}`;
Причем если в структуре добавится, например, поле email, в запрос нужно чтобы добавилось и это поле.
Я сделал функцию, которая собирает часть запроса, но она не расставляет кавычки для текстовых полей, не правильно показывает даты и т. п.
function getFields(object) {
var fields = '';
for (var key in object) {
fields += key + ' = ' + object[key] + ', ';
}
return fields.slice(0, -2);
}
Как такое делается на JavaScript?
|
|
05.04.2019, 02:41
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
SET id =1 и WHERE id =${obj.id} - в этом ничего странного нет?
|
|
05.04.2019, 10:07
|
Аспирант
|
|
Регистрация: 03.01.2018
Сообщений: 38
|
|
А по существу профессору ответить нечего?
|
|
05.04.2019, 10:26
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Сообщение от Elfix
|
А по существу профессору ответить нечего?
|
То есть это так, не существенно, когда уникальный идентификатор бог знает для чего обновляется? Это как минимум глупая операция.
Кроме этого, где происходит формование этого запроса - на сервере или клиенте?
|
|
05.04.2019, 13:14
|
Аспирант
|
|
Регистрация: 03.01.2018
Сообщений: 38
|
|
Мой вопрос связан с тем, как структуру перевести в список полей и присвоений значений в операции SQL UPDATE. Ваше замечание об id хотя и является по вашему мнению глупостью, к сути вопроса и к не учебной программе отношения не имеет.
Сложность заключается в том, что у меня значения полей в приведенном мной примере не заключаются в кавычки, как это положено по правилам SQL, или дата не соответствует стандарту SQL.
Работаю я на сервере, использую pg-promise.
Думаю в JavaScript есть какой-то изящный способ сформировать строку запроса быстрым и удобным способом. Но так как плохо знаком с существующими библиотеками вынужден интересоваться у общественности.
|
|
05.04.2019, 13:38
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Сообщение от Elfix
|
замечание об id хотя и является по вашему мнению глупостью, к сути вопроса и к не учебной программе отношения не имеет
|
Ну что же, давайте и это рассмотрим.
Не известно откуда эти данные, но явно, если бы мы в сценарии сначала сами же прописали их, а затем подставляли бы их в запрос, то это было бы вообще несусветной глупостью, так ведь? Следовательно эти данные откуда либо приходят. И тут возникает вопрос - откуда? Если это данные извне, то есть пришли на сервер от клиента, то мало заключить строковые значения в кавычки, обязательно перед этим произвести их экранирование средствами SQL. В противном случае запрос будет подвержен sql инъекции.
Второе. Вот что вы делаете - SET id =1 для WHERE id =${obj.id}. То есть, вы не знаете реальное id записи, которую будет обновлять и при этом принудительно меняете ее id. Это по вашему мелочи?
Если данные извне и вы эти данные помещаете в базу, то данные нужно проверять на соответствие типов, в противном случае в базе будет либо мусор, либо (при умной архитектуре таблиц) запрос вернет ошибку. Уникальные идентификаторы полученные средствами SQL не могут иметь значений равных 0, то есть приведение id к числу не только обезопасит запрос при вставке а него значения, но и позволит не делать пустой запрос, если id фикция.
Вот и думайте теперь, есть ли "мелочи" при работе с базами данных.
|
|
05.04.2019, 14:17
|
Аспирант
|
|
Регистрация: 01.03.2013
Сообщений: 77
|
|
думаю, здесь нужно проверять значение на типы
например, если typeof('string') === 'string', дописывать к строке кавычки
если дата, то проверять на дату Object.prototype.toString.call(new Date()) === "[object Date]" и уже приводить к правильной строке даты
пример:
function getFields(object) {
var fields = '';
for (var key in object) {
let value;
if (typeof(object[key] == 'string')) value = `"${object[key]}"`;
else if (Object.prototype.toString.call(object[key]) === "[object Date]") value = `"${object[key].getFullYear()}.${(object[key].getMonth()+1).toString().padStart(2,0)}.${object[key].getDate().toString().padStart(2,0)}"`
fields += key + ' = ' + value + ', ';
}
return fields.slice(0, -2);
}
Последний раз редактировалось NeoN, 05.04.2019 в 14:28.
|
|
05.04.2019, 14:53
|
|
Профессор
|
|
Регистрация: 08.11.2017
Сообщений: 641
|
|
<script>
const obj = {
id: 1,
firstName: 'Вася',
birthday: new Date()
}
const toLocale = date => date.toLocaleDateString('ru', {year: 'numeric', month: '2-digit', day: '2-digit'})
const fields = obj => {
return Object.keys(obj).map(key => {
switch (typeof obj[key]) {
case 'string':
return `${key} = '${obj[key]}'`
case 'number':
return `${key} = ${obj[key]}`
default:
return `${key} = '${toLocale(obj[key])}'`
}
}).join(', ')
}
const str = `UPDATE users SET ${fields(obj)} WHERE id = ${obj.id}`;
console.log(str)
</script>
p.s. после сборки доработать напильником %)
|
|
05.04.2019, 15:00
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
SuperZen, и все что требуется?
|
|
05.04.2019, 15:01
|
Аспирант
|
|
Регистрация: 01.03.2013
Сообщений: 77
|
|
Сообщение от SuperZen
|
<script>
const obj = {
id: 1,
firstName: 'Вася',
birthday: new Date()
}
const toLocale = date => date.toLocaleDateString('ru', {year: 'numeric', month: '2-digit', day: '2-digit'})
const fields = obj => {
return Object.keys(obj).map(key => {
switch (typeof obj[key]) {
case 'string':
return `${key} = '${obj[key]}'`
case 'number':
return `${key} = ${obj[key]}`
default:
return `${key} = '${toLocale(obj[key])}'`
}
}).join(', ')
}
const str = `UPDATE users SET ${fields(obj)} WHERE id = ${obj.id}`;
console.log(str)
</script>
p.s. после сборки доработать напильником %)
|
а база данных точно примет дату в таком формате - "05.04.2019" ?
|
|
|
|