In the go sql package, I understand that each statement should be closed after execution.
Why would someone use prepared statements instead of just the raw Query or Exec methods?
Prepared statement already bound to concrete connection to DB, contains low-level driver.Stmt and can be used concurrently by multiple go-routings. So it's quite handy to prepare and use, and things work faster.
I think the best answer comes from the wikipedia article on Prepared Statements.
Quoting:
The overhead of compiling and optimizing the statement is incurred
only once, although the statement is executed multiple times. Not all
optimization can be performed at the time the prepared statement is
compiled, for two reasons: the best plan may depend on the specific
values of the parameters, and the best plan may change as tables and
indexes change over time.`enter code here
Prepared statements are resilient against SQL injection, because
parameter values, which are transmitted later using a different
protocol, need not be correctly escaped. If the original statement
template is not derived from external input, SQL injection cannot
occur.
Related
When dealing with SQL Server and dates that are clustered indexes, in order to properly access the index the query must be in the form of:
select fields
from dbo.MyTable
where myDate between #begDate and #endDate
The between operator is what triggers the clustered seek. How can I tell LINQ to emit the between operator instead of >= this and <= that?
Unfortunately, Linq does not have a between operator or equivalent. The best (and possibly) only way to achieve this is in sql.
If you are looking to write complex or optimized queries, it is better to use sql rather than linq. The main advantages for this are:
Code can be fully tested in management studio, without having to translate and debug in a second language
For legacy purposes, it is generally better to use sql for database access code, as this is more widely known amongst database experts. LINQ is the curse of DBAs who have to manage/support code written by others.
I agree with Gerge Mauer's suggestion to use a stored procedure or ADO.
This might still leave you with the problem of parameter sniffing, in which case you may have to use query hints such as OPTIMIZE FOR / RECOMPILE, or local variables to get around this, as demonstrated in this article:
http://blogs.msdn.com/b/turgays/archive/2013/09/10/parameter-sniffing-problem-and-workarounds.aspx
On one of my customers sites I think I've found a big security issue.
I found out that when I entered an semicolon ' in the search box, the script threw an sql error. So I started playing...
Entering the SQL command below in the searchbox executes the query:
'+AND+product_description.description+LIKE+'%Computers%
The query is executed on the database!
Is it safe to say that a hacker can do harm with executing selects, inserts and delete queries too? Based on the fact that my query is executed I'm almost sure it should be possible to do harm... Am I right?
Yes, you're right. You should always sanitize the input and not use it directly in such a way, or it's sooner or later will be compromised by SQL injection attacks.
Yes, you are right. This code is open for sql injection attacks.
That definitely is a form of SQL injection, and you're correct in being worried.
However, that alone is not enough to tell whether or not you can do things other than alter the query parameters in unexpected ways. The query might for example be altered to retrieve data from tables not listed in the original query, which might well be bad enough.
I strongly recommend to avoid using string concatenation in building SQL queries, but instead using "prepared statements" which only allow to replace provided placeholders with the user-selected data values. Even there the application would be wise to check the values for at least some sanity before passing them on to the database-
Your site is open to SQL injection attacks, and there is a lot you can do to protect it, but first short term thing I would recommend is create a user-id with only read-rights and use this ID for all queries. Hackers will still be able to extract data from your database, but won't be as easy to update or delete rows or tables...
Our application issues an NHibernate-generated SQL query. At application runtime, the query takes about 12 seconds to run against a SQL Server database. SQL Profiler shows over 500,000 reads.
However, if I capture the exact query text using SQL Profiler, and run it again from SQL Studio, it takes 5 seconds and shows less than 4,600 reads.
The query uses a couple of parameters whose values are supplied at the end of the SQL text, and I'd read a little about parameter sniffing and inefficient query plans, but I had thought that related to stored procedures. Maybe NHibernate holds the resultset open while it instantiates its entities, which could explain the longer duration, but what could explain the extra 494,000 "reads" for the same query as performed by NHibernate? (No additional queries appear in the SQL Profiler trace.)
The query is specified as a LINQ query using NHibernate 3.1's LINQ facility. I didn't include the query itself because it seems like a basic question of philosophy: what could explain such a dramatic difference?
In case it's pertinent, there also happens to be a varbinary(max) column in the results, but in our situation it always contains null.
Any insight is much appreciated!
Be sure to read: http://www.sommarskog.se/query-plan-mysteries.html
Same rules apply for procs and sp_executesql. A huge reason for shoddy plans can be passing in a nvarchar param for a varchar field, it causes index scans as opposed to seeks.
I very much doubt the output is affecting the perf here, it is likely to be an issue with one of the params sent in, or selectivity of underlying tables.
When testing your output from profiler, be sure to include sp_executesql and make sure your settings match (stuff like SET ARITHABORT), otherwise you will cause a new plan to be generated.
You can always dig up the shoddy plan from the execution cache via sys.dm_exec_query_stats
Can I avoid all SQL-injection attacks by using parameters?
And don't worry about any thing in SQL injection in this case?
Or are there some types of these attacks which require more care on the part of the programmer?
No, you can't avoid all SQL injection attacks by using parameters. Dynamic SQL is the real issue, and this can occur in stored procedures as well as in your application code.
E.g., this is prone to a SQL injection attack: your parameterized query passes a username to a stored procedure, and within the stored procedure the parameter is concatenated to a SQL command and then executed.
For an example of many kinds of SQL injection attacks, see this SQL Injection Cheat Sheet. You will see that simply escaping single quotes is just scratching the surface, and that there are many ways around that.
Yes and no. Yes, if all of your SQL statements are indeed static and use only parameters, then you're 100% protected from SQL injection attacks.
The problem comes when the parameters themselves are used to construct dynamic SQL statements. An example would be a stored procedure that generates a SQL statement dynamically for querying a multitude of different options, where a single monolithic statement would be impractical. While there are better solutions to this problem, this is a common one.
Yes you can avoid all SQL-injection attacks by using parameters, as long as you use parameters exclusively all the way down the call stack. For example:
Your app code calls a stored procedure or dynamic SQL in the database. That must use parameters to pass all values.
The stored procedure or dynamic SQL internally constructs a call to another stored procedure or dynamic SQL statement. That must also use parameters to pass all values.
Repeat ad-infinitum until you run out of code.
If you are programming in SQL Server, you can use sp_executesql to execute dynamic SQL, and it will let you define and pass parameterised values to the statement being executed.
If you are going to build a dynamic sql query with those parameters (passed to a stored procedure, for example) then there's a chance of sql injection if precautions are not taken.
You can always minimize the risk of SQL injection by using prepared statements, provided your database engine supports them.
Anyway, prepared statements is probably the most secure way of blocking SQL injections.
The problem is building the SQL statement dynamically.
For example, you might want to order the result based on the column the user selected. In most databases, you can't use parameters here ("ORDER BY ?" doesn't work). So you have to "ORDER BY " + column. Now, if "column" is a String, then the user of your web-application could inject code there (which is not easy, but possible).
I am trying to execute a query against a MySQL database.
The query is fairly complex it has 5 inner joins, including 1 join to itself and
it returns 3 pieces of information from 2 different tables.
We are using hibernate and till now I have used it for simple queries only.
I have written the sql query and tested it too. I am wondering how to implement this using
hibernate, can I execute plain sql statements with hibernate? If so what do I need, a separate hbm.xml?
If I use hibernate and execute the plain sql query can I still utilize caching later on?
Yes, you can execute plain SQL queries with Hibernate.
No, you don't need a separate hbm.xml mapping file (unless you WANT to separate sql queries from the rest, in which case you can do so). You can map your named SQL query the same way you do with named HQL queries.
Whether you will be able to "utilize caching" depends on what exactly you understand by "caching" and how you're going to map your SQL query; it's impossible to answer without knowing more details.
All that said, you may not need to resort to SQL query; HQL is quite powerful and it may very well be possible (assuming appropriate mappings exist) to write your query as HQL. Can you post relevant mappings / schemas and your SQL query?
I strongly recommend criteria queries over HQL queries. They are much closer to your program code without sacrificing any expression power. They DO however depend on relations to be explicitly mapped, otherwise they get quite complicated.
To speed up development, set property hibernate.show_sql=true, and play with the system in the debugger, using the "reload modified class" and "drop stack frame" features of the IDE+jvm until the SQL emitted looks like the one you've posted.