findAll validates input fields - node.js

I have problems with findAll(), it "fires" validation and that makes problems when I want to select/find a row by ID using LIKE... For example the query would look like this
SELECT * FROM table WHERE id LIKE '%345%'
In my model the id column is set to INTEGER so I get error message that says:
"%345%" is not a valid integer
Is there a way to skip the validation when I use findAll etc. or is it a bad idea, does the validation maybe prevent SQL injection?

You could form your where clause as follows
var id =345;
.findAll({where: ["id like ?", '%' + id + '%']});

Related

How to query fields with multiple values in Azure Cognitive Search

Working on Azure Cognitive Search with backend as MS SQL table, have some scenarios where need help to define a query.
Sample table structure and data :
Scenarios 1 : Need to define a query which will return data based on category.
I have tied query using search.ismatch but its uses prefix search and matches other categories as well with similar kind of values i.e. "Embedded" and "Embedded Vision"
$filter=Region eq 'AA' and search.ismatch('Embedded*','Category')
https://{AZ_RESOURCE_NAME}.search.windows.net/indexes/{INDEX_NAME}/docs?api-version=2020-06-30-Preview&$count=true&$filter=Region eq 'AA' and search.ismatch('Embedded*','Category')
And it will response with below result, where it include "Embedded" and "Embedded Vision" both categories.
But my expectation is to fetch data only if it match "Embedded" category, as highlighted below
Scenario 2: For the above Scenario 1, Need little enhancement to find records with multiple category
For example if I pass multiple categories (i.e. "Embedded" , "Automation") need below highlighted output
you'll need to use a different analyzer which will break the tokens on every ';' just for the category field rather than 'whitespaces'.
You should first ensure your Category data is populated as a Collection(Edm.String) in the index. See Supported Data Types in the official documentation. Each of your semicolon-separated values should be separate values in the collection, in a property called Category (or similar).
You can then filter by string values in the collection. See rules for filtering string collections. Assuming that your index contains a string collection field called Category, you can filter by categories containing Embedded like this:
Category/any(c: c eq 'Embedded')
You can filter by multiple values like this:
Category/any(c: search.in(c, 'Embedded, Automation'))
Start with clean data in your index using proper types for the data you have. This allows you to implement proper facets and you can utilize the syntax made specifically for this. Trying to work around this with wildcards is a hack that should be avoided.
To solve above mention problem used a below SQL function which will convert category to a json string array supported by Collection(Edm.String) data type in Azure Search.
Sql Function
CREATE FUNCTION dbo.GetCategoryAsArray
(
#ID VARCHAR(20)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #result NVARCHAR(MAX) = ''
SET #result = REPLACE(
STUFF(
(SELECT
','''+ TRIM(Value) + ''''
FROM dbo.TABLEA p
CROSS APPLY STRING_SPLIT (Category, ';')
WHERE p.ID = #ID
FOR XML PATH('')
),1,1,''),'&','&')
RETURN '[' + #result + ']'
END
GO
View to use function and return desired data
CREATE View dbo.TABLEA_VIEW AS
select
id
,dbo. GetCategoryAsArray(id) as CategoryArr
,type
,region
,Category
from dbo.TABLEA
Defined a new Azure Search Index using above SQL View as data source and during Index column mapping defined CategoryArr column as Collection(Edm.String) data type
Query to use to achieve expected output from Azure Search
$filter=Region eq 'AA' and CategoryArr/any(c: search.in(c, 'Embedded, Automation'))

Writing a subquery to display records in a grid

I have two DAC's POReceipt, and and POReceiptLine. POReceiptLine containts a field called MfrPartNbr.
I want the user to be able to lookup all the POReceipts where the POReceiptLine.MfrPartNbr is equal to an entered value.
The SQL would be
SELECT *
FROM dbo.POReceipt
WHERE POReceipt.ReceiptNbr IN
(
SELECT ReceiptNbr
FROM dbo.POReceiptLine
WHERE MfrPartNbr = 'MY_ENTERED_PART_NBR'
)
Any idea how to write the BQL Statement for this?
As stated, an inner join won't work in this case because you will receive the same POReceipt multiple times (once for each POReceiptLine). The following BQL query shows how you can get the desired results using a sub query. If mfrPartNbr is an extension field, then replace POReceiptLine.mfrPartNbr with the correct extension name (e.g. POReceiptLineExtension.mfrPartNbr).
PXSelect<POReceipt, Where<Exists<
Select<POReceiptLine,
Where<POReceiptLine.receiptNbr, Equal<POReceipt.receiptNbr>,
And<POReceiptLine.mfrPartNbr, Equal<Required<POReceiptLine.mfrPartNbr>>>>>>>>.Select(this, "MY_ENTERED_PART_NBR");

SQL injection ,why should you write 0 or 1=1

In SQL injection, why should you use 0 or 1=1, isn't this automatically evaluated as 1 in boolean operation? I don't understand why we should write it that way. Can someone explain?
Thanks in advance
Because it makes the condition always true.
For example, if someone's SQL code is:
string query = "SELECT * FROM Users WHERE Password = '" + somePassword + "'";
(Username clause omitted for brevity.)
Then you can enter something like this as the password:
' OR 1 = 1;--
Which would make the resulting query:
SELECT * FROM Users WHERE Password = '' OR 1 = 1;--'
The semicolon ends the statement, and -- denotes a comment so everything thereafter is ignored. So it simplifies to:
SELECT * FROM Users WHERE Password = '' OR 1 = 1
This will match all records in the table. Always. Because 1 = 1 is always true. Depending on how the application handles this response, you may be logged in. Perhaps even as the first user in the table, which is likely to be the admin user.
For SQL-injectable code, it's basically a universal password. (Provided you guess a correct username, which isn't difficult.)
Edit: I just noticed the 0 part of your question as well. This would be used when you expect the injected value to be looking for a number rather than a string. For example, consider a similar SQL statement:
string query = "SELECT * FROM Users WHERE Id = " + someID;
The leading 0 in the injected value prevents a syntax error. So the resulting query would be:
SELECT * FROM Users WHERE Id = 0 OR 1 = 1
Same concept as above. This will match all records every time.
Here is a brief explanation for this:-
select title, text from news where id=$id
In the example above the variable $id contains user-supplied data, while the remainder is the SQL static part supplied by the programmer; making the SQL statement dynamic.
Because the way it was constructed, the user can supply crafted input trying to make the original SQL statement execute further actions of the user's choice. The example below illustrates the user-supplied data “10 or 1=1”, changing the logic of the SQL statement, modifying the WHERE clause adding a condition “or 1=1”.
select title, text from news where id=10 or 1=1
so the query will still get executed

Automapper Project().To Error A query body must end with a select

I'm trying to prevent that a query to an entity bring more columns than necessary. Should only bring those columns specified in the target model.
Below is my code built following some examples to achieve my goal but I get syntax error "A query body must end with a select clause or a group clause linq”
int the query line.
var studentEventsModel = from c in DbContext.StudentEvent.Project().To<StudentEventViewModel>();
Please let me know what I’m doing wrong.
public IEnumerable<StudentEventViewModel> GetStudentEventsListViewModel()
{
Mapper.CreateMap<StudentEvent, StudentEventViewModel>();
var studentEventsModel = from c in DbContext.StudentEvent.Project().To<StudentEventViewModel>();
return studentEventsModel;
}
As #hometoast mentioned you may add select at the end of your query like this:
var studentEventsModel =
from c in DbContext.StudentEvent.Project().To<StudentEventViewModel>() select c;
or alerternatively you may use the lambda expression like this:
var studentEventsModel = DbContext.StudentEvent.Project().To<StudentEventViewModel>();
And as to the question on why you are seeing that error, it is due to the fact that a query syntax must end with select or group, mentioned here in the documentation.
A query expression must begin with a from clause and must end with a
select or group clause. Between the first from clause and the last
select or group clause, it can contain one or more of these optional
clauses: where, orderby, join, let and even additional from clauses.
You can also use the into keyword to enable the result of a join or
group clause to serve as the source for additional query clauses in
the same query expression.

How to get last insert id when using sub query in Kohana

How do I return the correct $insert_id when using a sub query in Kohana?
I'm using the query method to return $insert_id and $affected_rows. It returns the correct value for $affected_rows but returns '1' for $insert_id which is incorrect.
Query below:
$sub = DB::select('id', 'username', 'email', 'lastVisitDate')->from('jos_users');
$qry_migrate_users = DB::insert('temp_users', array('old_id', 'username', 'email_work', 'last_login'))->select($sub);
list($insert_id, $affected_rows) = $qry_migrate_users->execute($this->conn_target);
MySQL returns only last insert id and affected rows. there is only one way to do what you want - execute your sub-select to array, and using foreach do single inserts. But it's a lilte bit slower operation! Or after inserting do something like that:
SELECT id FROM temp_users WHERE email IN (select email from jos_users)
You might understand the logic

Resources