SQL View vs Microsoft Access Query - sql

While most SQL Databases allow you to create a view, Microsoft Access has saved queries. I have read that Access Queries are not the same thing as SQL views, but that’s a sweeping statement.
I am aware that they have some differences in detail. For example Access saves SELECT * as is, while most saved views spell out the field list.
Aside from details such as these, is there a fundamental difference between the two?
Thanks

An Access "saved query" is more than a view in SQL Server (where "more" doesn't mean that it is better or not). In SQL Server you have the SQL text and the execution plan which defines a view. You can also add additional informations like description text or user defined variables with user defined values which have no influence on the view itself.
In Access you work with QueryDef objects, which are in fact the "saved queries", they contain a lot more than only the SQL text which is only one property of the QueryDef object. For example, you can define parameters with the PARAMETERS clause which can be used similar to #-variables in SQL Server stored procedures/functions. That's something which doesn't exist for SQL Server views. Of course a QueryDef object has also a saved exection plan, that's why Microsoft also recommends to use a QueryDef as i.e. form RecordSource instead of a dynamic SQL command at the same place. The JET/ACE query optimizer's result can also made visible with some registry tricks, it's only not part of the Access GUI so most people don't know that it also has an execution plan.
QueryDef objects contains also formatting properties, captions to be displayed in Datasheet view, definition of lookups for comboboxes, ODBC connection strings and a lot more, you can find them all in the Access help.
So Access QueryDefs contains a lot which only affects the display of the result which makes sense for a frontend which you can develop with Access, but they do not have very much advantages in comparison with SQL Server views. One simple difference is the SQL language: Independent of the backend you use you are working with Access SQL and this SQL is really a very basic SQL. T-SQL on SQL Server for example is a very powerful SQL language where you can do a lot more with - for example, you can query a hierarchical structure like a BOM (Bill Of Material) with one SQL statement which you can't with Access SQL as T-SQL can use recursive SQL. In Access it would only be able by using VBA functions in Access SQL which slows down the complete query a lot.
Of course a QueryDef object in Access can also use so called "Pass-Through-Queries" which executes i.e. T-SQL directly without using Access SQL. But as the SQL text is saved locally in Access it is handled as dynamical SQL in SQL Server because the text is sent each time it is executed and SQL Server has no saved view for that, so all the advantages of a saved view are lost. It's better to avoid them or use them only to execute saved views, functions or stored procedures on SQL Server.
A QueryDef object is moreover a DAO object and that means that you are working with DAO datatypes always. So even in case of a Pass-Through-Query the data is always converted from SQL Server (or of course other database) datatypes to DAO datatypes.
Easier deployment like mentioned above: Here's no big difference in using a view or a QueryDef in Access if both are used for frontend purposes like a form's RecordSource property. The reason is that a QueryDef and a view would both need to be implemented in the frontend, the QueryDef need to be changed locally, the view can be changed in the backend, but as it is in most cases linked to the frontend as linked table you need to delete this link in the frontend and recreate it in case of changes of the view so you also need to redeploy the frontend again (that's why I personally prefer ADPs instead of ACCDBs because in ADPs I work in Access directly with the view and not with any QueryDef so here a change in the backend is enough to reflect it in the frontend).
Independent of that you would also need to redeploy the frontend if you change a fieldname in the view you use in the frontend.
It is another thing if you use the view only in the backend to assemble data for other backend purposes like using it in a stored procedure or another view. If they are not linked to the frontend you don't need to redeploy the frontend. So as with stored procedures and functions it is also true for views that you can quickly change something in the backend if you need to fix something which doesn't affect the frontend directly. I.e., if you concatenate two text fields with a "." with an alias name and someone tells you that it now must be a "-" instead you can simply change the view and it's done, nothing to change in the frontend (if you have no further logic in the frontend which needs to check for the dot).
SELECT *
"spells out the field list" is indeed what a SQL Server view does, the problem is: It saves a list of fields of the table object you use in the SELECT at the time you save the view. But it doesn't save this field list visibly. If you open the view's SQL text you will always only see the "*", not the field list the view has saved. This is a big problem in SQL Server as you would expect that it lists all fields that the table has at all times (that's what Access does in a QueryDef object with SELECT *). So even if you use a tool like RedGate's free SQL Search you would not find that view as you have not the field list in the SQL text so the field name of a changed table field cannot be found.
In general avoid the "SELECT *" whereever possible as it produces more problems than that it has any advantage. Always use the list of fields you really want as result. In Access those field names will automatically be changed if you change the field name in a table (if you have AutoRename on in Access options), in SQL Server you can search for all objects using a specific field and change it.
One exception would be if you use a CTE in SQL Server where the last SELECT selects all fields of previous SELECTs in the CTE. Here it is no problem to use the asterisk as the field names are (should) be listed in the previous SELECTs of the same query. But in general it's better to more often avoid using it as using it for production purposes.
These are only examples of differences between both, there are a lot more like mentioned above (indexed views, security model) or something like schema names but this should give you a picture.

Very broadly speaking Views offer:
Performance
Benefit from Execution Plans which in the case of non-index Views will analyse the query using the View and the queries that make up the View definition. These plans are then stored so that repeated and/or similar queries can retrieve data faster. For reference: View Resolution
Indexed Views for situations such as when the underlying tables are not hugely transactional (OLTP) and dataset is large and requires aggregation such as in OLAP sources. For reference: Improving Performance with SQL Server 2008 Indexed Views
Security
Allows you to present a subset of data without granting access to the base Views or Tables that make up the View.
Easier Deployment
With Access, you make a change to your saved query, you would most likely have to roll-out that Access database to all users. With a View, you make a change and that'll affect all users.
Regarding the last point, that assumes you aren't changing identifiers in the View that are referenced elsewhere. A simple example would be changing a column name in the View. This would most likely require name changes in other dependent database objects or external tools that access it.
I am aware that they have some differences in detail. For example Access saves SELECT * as is, while most saved views spell out the field list.
That's not strictly true. It's generally preferred to identify columns by name in a View since they represent a subset of data and it restricts what data is seen by the end-user. That said, in general, any SQL query you can obviously restrict columns that are included, whether it's an Access Query or not. But you'll still come across Views with SELECT * so it's not a difference per se.

Related

Trying to get the relevant details of all the database

I am trying to get everything
find all the tables, views, stored procedures, scalar functions, table functions, schema using sql query of a specific database
I actually wanted to create a autocomplete option but as of now my first step is to get everything in a list but not sure how i will get all of the above of a specific database
This is a bit long for a comment.
You need to look into the system tables. Personally, I prefer the standard INFORMATION_SCHEMA views, but the information you want is spread out.
In SQL Server, you can use sys.objects, paying attention to the object type. The place to start learning about it is in the documentation.

If all SQL is doing is SELECT, is there an advantage to using a view vs a SPROC

If all SQL is doing is SELECT, is there an advantage to using a view vs a SPROC.
From my point of view, it's purely organizational, but I am wondering if there is a good reason for using views when all a SPROC is doing is SELECTs and has no writes to the DB.
I'm on Sql Server 2008 but this can probably apply to other SQL server products
Views are meant to abstract out the details of the underlying table and provide a window to the data, the way you want it to appear.
Stored procedures achieve a specific task and optionally take parameters that would be used during the task execution.
If you would like to run a specific task by taking arguments from the users, then you can create a stored procedure.
If you just want to expose data in a given way and leave further filtering, if required, to the users, you can create a view.
Other than the security advantage of encapsulating specific data for specific roles, there's also the advantage of being able to create an index on the view.
Here are some specific performance advantages, from the MSDN link:
Aggregations can be precomputed and stored in the index to minimize expensive computations during query execution.
Tables can be prejoined and the resulting data set stored.
Combinations of joins or aggregations can be stored.

What is the right way to do a multi-table join query in ASP.NET to SQL Server via LINQ?

I'm working on an ASP.NET 4.0 site, which I inherited ownership of.
It has a number of existing LINQ datasources pointing to individual tables. For example, to the Patient Encounter Summary table in SQL Server.
The problem is in displaying the data there. It's a normalized database, so that table contains (for example) the provider ID, rather than the provider name.
It's simple enough to join the Patient Counter Summary to the Providers table (in SQL)... but how does one do that in ASP.NET? I'm not sure of the correct nomenclature, but the 'mid layer' is VB.
So, the existing LinqDataSource entries are all to individual tables. I tried building a view in SQL Server to do all the joins, but the LinqDataSource doesn't 'see' such views as an option... even if it's read-only (no update, delete, or insert).
Please pardon my ignorance, but it looks like it should be so simple. For example, I have things like <asp:Label ID="Label12" runat="server" Text='<%# Bind("AttendingPhysicianID") %>'></asp:Label>... that it appears to me would be so simple if the LINQ DataSource was a view that joined the tables so I could change it to PhysicianName coming from the Physicians table.
Any guidance would be most appreciated... ideally at the level of 'this guy doesn't know anything'. :-) That is, I've seen all sorts of what looks like VB code on answers to similar questions, but don't know how to implement that within this structure.
Thanks much.
I would recomment to bookmark 101 LINQ samples, it is quite helpful.
Here is answer to your question: http://msdn.microsoft.com/en-us/vstudio/bb737909
Although this question is to do with LinqToSql joins, you state you are attempting to do this because you couldn't expose a pre-written SQL View via the Linq DataSource.
If there is value in using the SQL View you've written, and in having that view accessible outside your VB libaries, I would suggest going the first route and getting the LinqDataSource to expose your SQL View.
Try looking here:
http://msdn.microsoft.com/en-us/library/bb384396.aspx
You're using a System.Web.UI.WebControls.LinqDataSource. Imo, this is a control that lets you use strings to opaquely interact with (what was) a compiler verified query generation technology.
Here's a link to the documentation.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.linqdatasource.aspx
Here's some relevant passages:
Select - Gets or sets the properties and calculated values that are included in the retrieved data.
The LinqDataSource control enables you to use LINQ in an ASP.NET Web page by setting properties in markup text. The LinqDataSource control uses LINQ to SQL to automatically generate the data commands.
When you are querying a database... You then set the ContextTypeName property to the class that represents the database and set the TableName property to the property that represents the database table.
5.Select (specify which fields or properties to return).
However, if you set the Select property, it means that automatic update, insert, and delete operations cannot be enabled.
So I would think you could include a subquery in the select property to convert an Order.CustomerId into a Customer.Name
But if I were in your shoes, I would abandon the LinqDataSource and just write LinqToSql compiler verified queries.

Disable all queries in SQL Server that don't use named parameters?

It seems that one could stop all threat of Sql injection once and for all by simply rejecting all queries that don't use named parameters. Any way to configure Sql server to do that? Or else any way to enforce that at the application level by inspecting each query without writing an entire SQL parser? Thanks.
Remove the grants for a role to be able to SELECT/UPDATE/INSERT/DELETE against the table(s) involved
Grant EXECUTE on the role for stored procedures/functions/etc
Associate the role to database user(s) you want to secure
It won't stop an account that also has the ability to GRANT access, but it will stop the users associated to the role (assuming no other grants on a per user basis) from being able to execute queries outside of the stored procedure/functions/etc that exist.
There are only a couple ways to do this. OMG Ponies has the best answer: don't allow direct sql statements against your database and instead leverage the tools and security sql server can provide.
An alternative way would be to add an additional tier which all queries would have to go through. In short you'd pass all queries (SOA architecture) to a new app which would evaluate the query for passing on to sql server. I've seen exactly one company do this in reaction to sql injection issues their site had.
Of course, this is a horrible way of doing things because SQL injection is only one potential problem.
Beyond SQL Injection, you also have issues of what happens when the site itself is cracked. Once you can write a new page to a web server it becomes trivial to pass any query you want to the associated database server. This would easily bypass any code level thing you could put in place. And it would allow the attacker to just write select * from ... or truncate table ... Heck, an internal person could potentially just directly connect to the sql server using the sites credentials and run any query they wanted.
The point is, if you leverage the security built into sql server to prevent direct table access then you can control through stored procedures the full range of actions availble to anyone attempting to connect to the server.
And how do you want to check for that? Queries sometimes have constant values that would just as easy be added to the query. For instance, I have a database that is prepared to be multi lingual, but not all code is, so my query looks like this:
SELECT NAME FROM SOMETABLE WHERE ID = :ID AND LANGUAGEID = 1
The ID is a parameter, but the language id isn't. Should this query be blocked?
You ask to block queries that don't use named parameters. That can be easily enforced. Just block any query that doesn't specify any parameters. You can do this in your application layer. But it will be hard to block queries like the one above, where one value is a parameter and the other one isn't. You'll need to parse that query to detect it, and it will be hard too.
I don't think sql server has any built in features to do this.

What is the best way to create an enhanced Data Dictionary?

Without going into specifics...I have a large SQL Server 2005 database with umpteen stored-procedures.
I have multiple applications from WinForm apps to WebServices all of which use this DB.
My simple objective now is to create a meta-database...a prospective data-dictionary where I can maintain details of which specific app. file uses which SP.
For example, My application Alpha which has a file Beta.aspx...uses 3 SPs which are physically configured for usage in BetaDAL.cs
You might have inferred by now,it will make life easier for me later when there is a migration or deprecation....where I can just query this DB SP-wise to get all Apps/Files that use the DB or vice-versa.
I can establish this as a single de-normalized table..or structure it in a better way.
Does some schema already exist for this purpose?
SQL Server supports what are called extended properties, basically a key-value dictionary attached to every object in the catalog. You can add whatever custom information about the catalog (comments on tables, columns, stored procedures, ...) you wish to store as extended properties and query them along with the normal catalog views.
Here's one overview (written for SQL Server 2005, but roughly the same techniques should apply for 2000 or 2008).