传递参数时调用了错误的命名查询 Node.js
Wrong named query gets called when passing parameters Node.js
我刚开始使用 Node.js、PostgresSQL 和 pg-promise,在我的 API 的获取端点中,我检查存在哪些参数,如果 city, region, country
是present 我调用 'get-city-products'
查询,如果存在 region, country
我调用 'get-region-products'
,如果存在 country
我调用 'get-country-products'
。
当我只通过 region, country
或 country
它调用 'get-city-products'
,没有 city
或 city, region
失败并且 return 没有产品..
为什么缺少 city
参数时 else if (city, region, country)
会成功?你能发现我的业务逻辑有什么问题吗?
这是固有代码:
// city
else if (city, region, country) {
await db.any({
name: 'get-city-products',
text: 'SELECT * FROM products WHERE city = AND region = AND country = ',
values: [city, region, country]
})
.then(result => {
console.log('get-city-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-products error:', error);
});
}
// region => never gets called
else if (region, country) {
await db.any({
name: 'get-region-products',
text: 'SELECT * FROM products WHERE region = AND country = ',
values: [region, country]
})
.then(result => {
console.log('get-region-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-region-products error:', error);
});
}
// country => never gets called
else if (country) {
await db.any({
name: 'get-country-products',
text: 'SELECT * FROM products WHERE country = ',
values: [country]
})
.then(result => {
console.log('get-country-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-country-products error:', error);
});
}
这里是完整的方法:
exports.findProducts = async (req, res) => {
// customers queries
// sorted
if (city, region, country, category, minPrice, maxPrice, orderedBy, sorted) {
/// this will create a unique PreparedStatement name for each query type
const name = 'getCityCategoryPriceRangeOrderedBy' + orderedBy + '' + sorted + ' Products';
const text = pgp.as.format(`SELECT * FROM products WHERE city = $/city/
AND region = $/region/ AND country = $/country/
AND category = $/category/
AND price BETWEEN $/minPrice/ AND $/maxPrice/
ORDER BY $/orderedBy:name/ $/sorted:value/`, {
city, region, country, category,
minPrice, maxPrice, orderedBy, sorted
});
console.log('query for ' + name + ' is: ', text,);
await db.any({ name: name, text: text })
.then(result => {
console.log(name + ' results: ', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log(name + ` error:`, error);
});
}
// price range
else if (city, region, country, category, minPrice, maxPrice) {
await db.any({
name: 'get-city-category-price-range-products',
text: 'SELECT * FROM products WHERE city = AND region = AND country = AND category = AND price BETWEEN AND ',
values: [city, region, country, category, minPrice, maxPrice]
})
.then(result => {
console.log('get-city-category-price-range-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-category-price-range-products error:', error);
});
}
// city category
else if (city, region, country, category) {
await db.any({
name: 'get-city-category-products',
text: 'SELECT * FROM products WHERE city = AND region = AND country = AND category = ',
values: [city, region, country, category]
})
.then(result => {
console.log('get-city-category-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-category-products error:', error);
});
}
// city
else if (city, region, country) {
await db.any({
name: 'get-city-products',
text: 'SELECT * FROM products WHERE city = AND region = AND country = ',
values: [city, region, country]
})
.then(result => {
console.log('get-city-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-products error:', error);
});
}
// region => never gets called
else if (region, country) {
await db.any({
name: 'get-region-products',
text: 'SELECT * FROM products WHERE region = AND country = ',
values: [region, country]
})
.then(result => {
console.log('get-region-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-region-products error:', error);
});
}
// country => never gets called
else if (country) {
await db.any({
name: 'get-country-products',
text: 'SELECT * FROM products WHERE country = ',
values: [country]
})
.then(result => {
console.log('get-country-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-country-products error:', error);
});
}
// shops queries
else if (vendor) {
await db.any({
name: 'get-vendor-products',
text: 'SELECT * FROM products WHERE vendor = ',
values: [vendor]
})
.then(result => {
console.log('get-vendor-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-vendor-products error:', error);
});
}
else {
db.any({
name: 'get-all-products',
text: 'SELECT * FROM products ORDER BY id ASC',
})
.then(result => {
console.log('get-all-products', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found'
});
}
})
.catch(function (error) {
console.log('get-cityProducts error:', error);
});
}
};
我应该只为每个查询使用 1 个参数吗?
在您的条件子句(else ifs)中,您使用逗号分隔不同的值
else if (city, region, country) {
虽然语法并非完全无效(仅使用最终变量的值),但您可能正在寻找布尔比较
else if (city && region && country)
如果所有变量都为真,则执行条件。
我刚开始使用 Node.js、PostgresSQL 和 pg-promise,在我的 API 的获取端点中,我检查存在哪些参数,如果 city, region, country
是present 我调用 'get-city-products'
查询,如果存在 region, country
我调用 'get-region-products'
,如果存在 country
我调用 'get-country-products'
。
当我只通过 region, country
或 country
它调用 'get-city-products'
,没有 city
或 city, region
失败并且 return 没有产品..
为什么缺少 city
参数时 else if (city, region, country)
会成功?你能发现我的业务逻辑有什么问题吗?
这是固有代码:
// city
else if (city, region, country) {
await db.any({
name: 'get-city-products',
text: 'SELECT * FROM products WHERE city = AND region = AND country = ',
values: [city, region, country]
})
.then(result => {
console.log('get-city-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-products error:', error);
});
}
// region => never gets called
else if (region, country) {
await db.any({
name: 'get-region-products',
text: 'SELECT * FROM products WHERE region = AND country = ',
values: [region, country]
})
.then(result => {
console.log('get-region-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-region-products error:', error);
});
}
// country => never gets called
else if (country) {
await db.any({
name: 'get-country-products',
text: 'SELECT * FROM products WHERE country = ',
values: [country]
})
.then(result => {
console.log('get-country-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-country-products error:', error);
});
}
这里是完整的方法:
exports.findProducts = async (req, res) => {
// customers queries
// sorted
if (city, region, country, category, minPrice, maxPrice, orderedBy, sorted) {
/// this will create a unique PreparedStatement name for each query type
const name = 'getCityCategoryPriceRangeOrderedBy' + orderedBy + '' + sorted + ' Products';
const text = pgp.as.format(`SELECT * FROM products WHERE city = $/city/
AND region = $/region/ AND country = $/country/
AND category = $/category/
AND price BETWEEN $/minPrice/ AND $/maxPrice/
ORDER BY $/orderedBy:name/ $/sorted:value/`, {
city, region, country, category,
minPrice, maxPrice, orderedBy, sorted
});
console.log('query for ' + name + ' is: ', text,);
await db.any({ name: name, text: text })
.then(result => {
console.log(name + ' results: ', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log(name + ` error:`, error);
});
}
// price range
else if (city, region, country, category, minPrice, maxPrice) {
await db.any({
name: 'get-city-category-price-range-products',
text: 'SELECT * FROM products WHERE city = AND region = AND country = AND category = AND price BETWEEN AND ',
values: [city, region, country, category, minPrice, maxPrice]
})
.then(result => {
console.log('get-city-category-price-range-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-category-price-range-products error:', error);
});
}
// city category
else if (city, region, country, category) {
await db.any({
name: 'get-city-category-products',
text: 'SELECT * FROM products WHERE city = AND region = AND country = AND category = ',
values: [city, region, country, category]
})
.then(result => {
console.log('get-city-category-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-category-products error:', error);
});
}
// city
else if (city, region, country) {
await db.any({
name: 'get-city-products',
text: 'SELECT * FROM products WHERE city = AND region = AND country = ',
values: [city, region, country]
})
.then(result => {
console.log('get-city-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-products error:', error);
});
}
// region => never gets called
else if (region, country) {
await db.any({
name: 'get-region-products',
text: 'SELECT * FROM products WHERE region = AND country = ',
values: [region, country]
})
.then(result => {
console.log('get-region-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-region-products error:', error);
});
}
// country => never gets called
else if (country) {
await db.any({
name: 'get-country-products',
text: 'SELECT * FROM products WHERE country = ',
values: [country]
})
.then(result => {
console.log('get-country-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-country-products error:', error);
});
}
// shops queries
else if (vendor) {
await db.any({
name: 'get-vendor-products',
text: 'SELECT * FROM products WHERE vendor = ',
values: [vendor]
})
.then(result => {
console.log('get-vendor-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-vendor-products error:', error);
});
}
else {
db.any({
name: 'get-all-products',
text: 'SELECT * FROM products ORDER BY id ASC',
})
.then(result => {
console.log('get-all-products', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found'
});
}
})
.catch(function (error) {
console.log('get-cityProducts error:', error);
});
}
};
我应该只为每个查询使用 1 个参数吗?
在您的条件子句(else ifs)中,您使用逗号分隔不同的值
else if (city, region, country) {
虽然语法并非完全无效(仅使用最终变量的值),但您可能正在寻找布尔比较
else if (city && region && country)
如果所有变量都为真,则执行条件。