Basic SQL count with LINQ - asp.net

I have a trivial issue that I can't resolve. Currently our app uses Linq to retrieve data and get a basic integer value of the row count. I can't form a query that gives back a count without a 'select i'. I don't need the select, just the count(*) response. How do I do this? Below is a sample:
return (from io in db._Owners
where io.Id == Id && io.userId == userId
join i in db._Instances on io.Id equals i.Id **select i**).Count()
;

The select i is fine - it's not actually going to be fetching any data back to the client, because the Count() call will be translated into a Count(something) call at the SQL side.
When in doubt, look at the SQL that's being generated for your query, e.g. with the DataContext.Log property.

Using the LINQ query syntax requires a select statement. There's no way around that.
That being said, the statement will get transformed into a COUNT()-based query; the select i is there only to satisfy the expression system that underlies the LINQ query providers (otherwise the type of the expression would be unknown).

Including the select will not affect the performance here because the final query will get translated into SQL. At this point it will be optimized and will be like select (*) from ......

Related

Do you need parameterized SQL searches if you check the inputs?

I'm writing an R Shiny/SQLite app. In the app, I have a function that returns a column from one of the tables in my SQLite database, with the function taking the table name as an input.
Before sending the query to SQLite, the function checks that the table name equals one of the table names that the user is allowed to access. However, I am not using a parameterized query, because the term I'm changing is not a variable used for comparison but the name of the table to extract information from. (There might be a way to make this work anyway with a parameterized search, I suppose.)
My question is whether this is safe from an SQL injection? Can the query be altered on its way from the server to the database, or only from an alteration in the ui input to the server?
(Bear with me, I am new to SQLite.)
Assuming your query is being concatenated as follows:
tbl <- "yourTable"
sql <- paste0("select * from ", tbl, " where some_col = 1")
Then there should be no chance of SQL injection, assuming you check the incoming table name and verify that it matches a table name in your whitelist. Note that this step is critical here to keeping things safe. Let's say that you didn't sterilize the incoming table name. Then, consider this:
tbl <- "yourTable; delete from yourTable"
This would result in the following query being submitted for execution:
select * from yourTable; delete from yourTable where some_col = 1;
Assuming your SQLite driver allows multiple SQL statements to execute, the above hack/trick might end up deleting data from a large portion of one of your tables.
So, your approach should be safe provided that you check the table name. Note that strictly speaking the table name itself is not a parameter in a parameterized query. Rather, only the literal values in the query are parameters.
SQL query parameters cannot be used in place of a table name anyway, so comparing the table name to a list of known authorized tables is your only option.
Yes, it is safe. If you're in control of the set of values that can be interpolated into the SQL query, then you can prevent unauthorized SQL injection.
Note that some other elements of SQL queries cannot be parameters:
Any identifier, e.g. a table name, column name, or schema name.
Expressions
Lists of values in an IN ( ... ) predicate. Use one parameter per value in the list.
SQL keywords.
A query parameter can be used only in place of a single scalar value. That is, where you would use a quoted string literal, quoted date literal, or numeric literal.
The problem of SQL injection is only the user input. Nothing happens to the query on its way from the server to the database (well a malware could in theory alter it, but then even a parametrized query wouldn't help).
I.e., if you create a SQL string like this (C#):
sql = "SELECT * FROM " + tableName;
Then a user might enter a tableName like
MyTable; DROP TABLE MyTable
Guess what happens.
So, if you check the table name, you are on the safe side.

Cosmos db Order by on 'computed field'

I am trying to select data based on a status which is a string. What I want is that status 'draft' comes first, so I tried this:
SELECT *
FROM c
ORDER BY c.status = "draft" ? 0:1
I get an error:
Unsupported ORDER BY clause. ORDER BY item expression could not be mapped to a document path
I checked Microsoft site and I see this:
The ORDER BY clause requires that the indexing policy include an index for the fields being sorted. The Azure Cosmos DB query runtime supports sorting against a property name and not against computed properties.
Which I guess makes what I want to do impossible with queries... How could I achieve this? Using a stored procedure?
Edit:
About stored procedure: actually, I am just thinking about this, that would mean, I need to retrieve all data before ordering, that would be bad as I take max 100 value from my database... IS there any way I can do it so I don t have to retrieve all data first? Thanks
Thanks!
ORDER BY item expression could not be mapped to a document path.
Basically, we are told we can only sort with properties of document, not derived values. c.status = "draft" ? 0:1 is derived value.
My idea:
Two parts of query sql: The first one select c.* from c where c.status ='draft',second one select c.* from c where c.status <> 'draft' order by c.status. Finally, combine them.
Or you could try to use stored procedure you mentioned in your question to process the data from the result of select * from c order by c.status. Put draft data in front of others by if-else condition.

Oracle 11g fetch values using offset value

I am trying to fetch set of records from the database part by part.
I tried to use Limit and fetch but it seems like it does not working with oracle 11g. Is there any alternative solution to do this. I have tried many in google results but nothing is working properly.
You can use this query and do what u want.
SELECT A.*
FROM (SELECT A.*, ROWNUM ROWNUMBER
FROM Table1 T
WHERE ROWNUM <= TO) T
WHERE ROWNUMBER > FROM;
FROM is from which number and TO is to which number
A Sound application is based on sound design. Kindly check if you are trying to achieve a procedural requirement using an SQL. If yes, it is better to use PL/SQL instead of SQL.
Create a cursor using the required SQL without any limits.
Create a type of associative array to hold the batch records.
Create an associative array using the type created above
Open and loop the cursor.
FETCH created_cursor BULK COLLECT INTO created_associated_array LIMIT ;
Hope this helps.

How to add a complex range expression to an AOT query in the AOT

I am working on a report, and for my data set i need to use an or statement. in SQL my query would look like:
SELECT recId, etc... FROM CustTrans
WHERE (CustTrans.Closed IS NULL AND CustTrans.Invoice IS NULL)
OR (CustTrans.Invoice IS NOT NULL)
I would translate this then into range like the following (stuck on the RecId field)
Value:
((CustTrans.Invoice == ‘’) && (CustTrans.Closed == ‘’) || (CustTrans.Invoice != ‘’))
I have found numerous places explaining that this is the proper syntax, although all of them are using the programmatic method of creating a query. I need to keep mine in the AOT so the customer can modify it later on if they want, and every combination of quotes, parens, and order still does not work. Sometimes AX will accept my range value string, but it doesn't do anything, and sometimes it will give me a random syntax error.
Is there a way to accomplish what I'm looking to do? have I missed some syntax, or does AX really not let you use OR on a query without a union and another view?
Thanks!
You can create a Query in the AOT and then over-ride the init method for the Query. Where you can put these complex SQL statements and get your work done.

Retrieve the PK using ##identity

I'm building a website using ASP.NET and SQL Server, and I use
SELECT PK FROM Table WHERE PK = ##identity
My question is which is better and more reliable to retrieve the last inserted PK for multiuser website, using ##identity or using this:
SELECT MAX(PK) FROM Table WHERE PK = Session ("UserID")
I'm not sure exactly what you want to achieve, but the recommended way to retrieve the primary key value of the last statement on a connection is to use SCOPE_IDENTITY()
##Identity is particularly risky where you are using triggers, since it returns the last generated identity value, including those generated by triggers flowing on from a statement.
MSDN has the following to say:
SCOPE_IDENTITY and ##IDENTITY return
the last identity values that are
generated in any table in the current
session. However, SCOPE_IDENTITY
returns values inserted only within
the current scope; ##IDENTITY is not
limited to a specific scope.
You should certainly use SCOPE_IDENTITY() in favour of the MAX(PK) approach - any number of possible future changes could invalidate this method.
For SQL Server 2005 and above...
You can do the INSERT and SELECT in one call using the OUTPUT clause...
INSERT MyTable (col1, col2, ..., coln)
OUTPUT INSERTED.keycol, INSERTED.col1, INSERTED.col2, ..., INSERTED.coln
VALUES (val1, val2, ..., valn)
Otherwise, you only use SCOPE_IDENTITY()
As mentioned by #David Hall the ##IDENTITY keyword returns the most recently created identity for your current connection, not always the identity for the recently added record in your query and may return an incorrect value. Using MAX(PK) there is a higher chance for an incorrect value and I'd strongly recommend against using it. To avoid the any race conditions I'd suggest that you use SCOPE_IDENTITY() to return the identity of the recently added record in your INSERT SQL Statement or Stored Procedure.
Depends on what you're trying to accomplish. If you want to return the just-generated ID to the ASP.NET code (a typical scenario), then ##identity is your friend. In a high-concurrency situation, mak(PK) is not even guaranteed to be the PK you're after.

Resources