Correct Nodejs mssql parameterized LIKE query syntax - sql-server

Using Nodejs and mssql package for SQL Server, I understand normal SELECT query with parameters:
aVar = "somestring"; // used as example, the real input is from a web form
request = new sql.Request(conn)
.input('aParam', sql.NVarChar(200), aVar);
q = "SELECT * FROM myTable WHERE theColumn = #aParam";
request.query(q, function(err, record) { ...
Those work just fine. Changing this to use LIKE, and I cannot get it to work. I've tried single quote before the % character, after, around it, just around the string, the whole thing, etc. Doing this:
q = "SELECT * FROM myTable WHERE theColumn LIKE " + "'%#aParam%'";
does not result in any errors, but returns no results. All other attempts with those single quotes results in query syntax errors. I cant seem to locate any documentation for parameterizing queries with wildcards. Where am I going wrong with this?

The syntax to do this is mentioned here - https://github.com/tediousjs/node-mssql/issues/332.
But in short:
q = `SELECT * FROM myTable WHERE theColumn LIKE '%' + #aParam + '%';`;

Unless you writing low level driver/worker, I would recommend to use any ORM:
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password');
const MyTable = sequelize.define('myTable', {
theColumn: Sequelize.STRING
});
const aVar = 'somestring';
const results = await MyTable.findAll({
where: {
theColumn: { $like: `%${aVar}%` }
}
});
})
console.dir(results);
await can be used only inside async functions. For Framework supporting this out of the box take a look at Koa.js https://github.com/koajs/koa

Related

Why does Snowflake variable binding in query throw error with table name but not integer?

I am following the Snowflake Python Connector docs for variable binding to avoid SQL injection. I successfully set up a db connection with the following dict of credentials:
import snowflake.connector
CONN = snowflake.connector.connect(
user=snowflake_creds['user'],
password=snowflake_creds['password'],
account=snowflake_creds['account'],
warehouse=snowflake_creds["warehouse"],
database=snowflake_creds['database'],
schema=snowflake_creds['schema'],
)
cur = CONN.cursor(snowflake.connector.DictCursor)
The following block works fine and I get back query results, hard-coding the table name and using the standard format binding:
command = ("SELECT * FROM TEST_INPUT_TABLE WHERE batch_id = %s")
bind_params = (2)
results = cur.execute(command % bind_params).fetchall()
Similarly, this block works fine, using the pyformat binding:
command = ("SELECT * FROM TEST_INPUT_TABLE WHERE batch_id = %(id)s")
bind_params = {"id": 2}
results = cur.execute(command, bind_params).fetchall()
But the following two blocks both result in a ProgrammingError (pasted below the second block):
command = ("SELECT * FROM %s WHERE batch_id = %s")
bind_params = ("TEST_INPUT_TABLE", 2)
results = cur.execute(command, bind_params).fetchall()
command = ("SELECT * FROM %(tablename)s WHERE batch_id = %(id)s")
bind_params = {
"tablename": "TEST_INPUT_TABLE",
"id": 2
}
results = cur.execute(command, bind_params).fetchall()
ProgrammingError: 001011 (42601): SQL compilation error:
invalid URL prefix found in: 'TEST_INPUT_TABLE'
Is there some difference between how strings and ints get interpolated? I would
not think it would make a difference but that is all I can think of. Am I
missing something simple here? I don't want to have to choose between hard-coding the table name and putting the system at risk of SQL injection. Thanks for any guidance.
You should be wrapping your bind variables with an INDENTIFER() function when they reference an object, rather than a string literal. For example:
command = ("SELECT * FROM IDENTIFIER(%(tablename)s) WHERE batch_id = %(id)s")
https://docs.snowflake.com/en/sql-reference/identifier-literal.html
Give that a try.

I'm trying to translate this sql query on Linq to sql query, but i have some difficult on Avg() and DateDiff()

select AVG(DATEDIFF(yyyy, (p.BirthDay), GETDATE()))
from Person p
I'm trying to translate this SQL query in a Linq to SQL query. My problems is with AVG() and DATEDIFF().
Try something like below
EF6
double resultAverage = ctx.Person.Average(p => DbFunctions.DiffDays(p.BirthDay, DateTime.Now));
EF4
double resultAverage = ctx.Person.Average(p => SqlFunctions.DateDiff("day" ,p.BirthDay, DateTime.Now));
tryAlso
double resultAverage = ctx.Person.Average(p => (DateTime.Now - p.BirthDay).Days);
**I SOLVED doing like below: **
var query = (from A in ctx.Persons
select new {
AverageAge = ctx.Persons.Average(p => (Convert.ToInt32(DateTime.Now.ToString("yyyy")) - Convert.ToInt32(p.BirthDay)))
}).Distinct();
NOTE: i have solved it like above because p.Birthday returns a string in "yyyy" format.
Or i could do it also by applying "Take(1)" instead of "Distinct()" like below:
var query = (from A in ctx.Persons
select new {
AverageAge = ctx.Persons.Average(p => (Convert.ToInt32(DateTime.Now.ToString("yyyy")) - Convert.ToInt32(p.BirthDay)))
}).Take(1);

SQL queries do not currently support returning aliases

I have this raw sql that I am trying to run on grails
final session = sessionFactory.currentSession;
final String query = 'select count(A.*) from Artifact as A LEFT JOIN classification as C on (A.id=C.artifact_id) where C.id IS NULL OR C.active=0';
final sqlQuery = session.createSQLQuery(query);
def totalunclass = sqlQuery.with {
addEntity(Artifact);
}
But I am getting the error Message: SQL queries do not currently support returning aliases
I tried another method but failed there too achieve the result click here
Try changing your query line to look like this
final String query = 'select count(*) from Artifact A LEFT JOIN classification C on (A.id=C.artifact_id) where C.id IS NULL OR C.active=0';
Try this and remove aliases:
final session = sessionFactory.currentSession;
final String query = 'select count(Artifact.*) from Artifact LEFT JOIN classification on (Artifact.id=classification.artifact_id) where classification.id IS NULL OR classification.active=0';
final sqlQuery = session.createSQLQuery(query);
def totalunclass = sqlQuery.with {
addEntity(Artifact);
}

Dapper and In Condition

Using Dapper, the following throws Incorrect syntax near ','.
const string sql =
"select * from ZipToZipDistance z where z.NoRouteFound = 0" +
" and z.OriginZip in (#zips) or z.DestZip in (#zips)";
var zipStrings = zips.Select(x => x.ToString()).ToArray();
var result = connection.Query<ZipToZipDistance>(sql,
new { zips = zipStrings });
Hmm, the SQL has no commas. It must have something to do with the parameter. OriginZip and DestZip are varchar(10). zips is IEnumerable<int>. I tried using zips as the parameter without the converting to strings. Same error.
Seems very straightforward. What am I doing wrong?
try:
const string sql =
const string sql =
"select * from ZipToZipDistance z where z.NoRouteFound = 0" +
" and z.OriginZip in #zips or z.DestZip in #zips";
var zipStrings = zips.Select(x => x.ToString());
var result = connection.Query<ZipToZipDistance>(sql,
new { zips = zipStrings });

How to insert a file into sql-server via tiny_tds?

In a data importing script:
client = TinyTds.Client.new(...)
insert_str = "INSERT INTO [...] (...) VALUE (...)"
client.execute(insert_str).do
So far so good.
However, how can I attach a .pdf file into the varbinary field (SQL Server 2000)?
I've recently had the same issue and using activerecord was not really adapted for what I wanted to do...
So, without using activerecord:
client = TinyTds.Client.new(...)
data = "0x" + File.open(file, 'rb').read.unpack('H*').first
insert_str = "INSERT INTO [...] (...) VALUE (... #{data})"
client.execute(insert_str).do
To send proper varbinary data, you need to read the file, convert it to hexadecimal string with unpack('H*').first and prepend '0x' to the result.
Here is PHP-MSSQL code to save binary data:
mssql_query("SET TEXTSIZE 2147483647",$link);
$sql = "UPDATE UploadTable SET UploadTable_Data = ".varbinary_encode($data)." WHERE Person_ID = '".intval($p_id)."'";
mssql_query($sql,$link) or
die('cannot upload_resume() in '.__FILE__.' on line '.__LINE__.'.<br/>'.mssql_get_last_message());
function varbinary_encode($data=null) {
$encoded = null;
if (!is_null($data)) {
$a = unpack("H*hex", $data);
$encoded = "0x";
$encoded .= $a['hex'];
}
return $encoded;
}
Here is PHP-MSSQL code to get binary data:
mssql_query("SET TEXTSIZE 2147483647",$link);
$sql = "SELECT * FROM UploadTable WHERE ID = 123";
$db_result = mssql_query($sql,$link);
// work with result like normal
I ended up using activerecord:
require 'rubygems'
require 'tiny_tds'
require 'activerecord-sqlserver-adapter'
..
my_table.create(:file_name => "abc.pdf", :file_data => File.open("abc.pdf", "rb").read)
For SQLServer 2000 support, go for 2.3.x version activerecord-sqlserver-adapter gem.

Resources