Finding the SQL output of a parameterized query - c#

I'm making a parameterized query using C# against a SQL server 2005 instance, and I'd like to take a look at the SQL that is run against the database for debugging purposes. Is there somewhere I can look to see what the output SQL of the parameterized command is, either in the database logs or in the Visual Studio debugger?

Use SQL Server Profiler to view the sql
http://www.eggheadcafe.com/articles/sql_server_profiler.asp
http://msdn.microsoft.com/en-us/library/ms187929(SQL.105).aspx

SQL Profiler is the best solution, but if you need something more organic to your application that you could deploy and enable/disable in production, QA, etc... then you could build a wrapper around the System.Data.SqlClient Provider (Ex. the provider registered in the config file as... providerName="System.Data.SqlClient").
This would essentially act like an intercept proxy which would give you access to all the information passing through the Provider (e.g. between your application and the database client). This would allow you to siphon-off what you need, intercept, modify, aggregate and/or enrich it. This is a bit more advanced but opens the door to capture a whole range of information and could be inserted/replaced/removed as a separate layer of concern.

Related

Disable DML queries in SQLCommand C#

Problem
I'm writing a GUI application that allows users to generate an Excel file based on SELECT SQL query user enters in TextBox. It will connect to SQL server, run select over database, fill DataTable object and push that data to an Exel file.
The way I have developed application is vulnerable for SQL injections and user may be able to pass any DML query such as DELETE OR UPDATE.
Question
Is there a way in SQLCLient library to prevent user from entering DML queries and executing them? Can I somehow enforce SQLCommand object to throw an exception when DELETE command is passed?
The correct way to do this is to create a database user with only select grants to the specified tables or views as described by BhavO and jean in comments.
Why is this the correct way to limit the T-SQL commands?
Doing it client-side is significantly more complex. There is a T-SQL parser library that is provided by Microsoft, but do you really want to spend your time writing and testing tree visitor code that ensures you only have SELECT commands that only query some certain tables? Also now you have to worry about keeping this parser library component up-to-date with SQL Server releases which might have new SELECT query syntax that is not understood by the older parser library and causes errors in your app. Why not delegate the T-SQL parsing to the component in your system that is already designed to do that, which is SQL Server?
Doing it client-side provides no actual security. Security of a server needs to be implemented by the server, not by its client code. The client code is running on the user's machine, so the user has total control over what is being executed. This means a malicious user can potentially (1) decompile and edit out the "DML disable" check component and then run the edited binaries, therefore skipping the check, or more practically (2) use network inspection tools to determine how your client app is connecting to the service (i.e. the connection string) and then just directly connect using that connection string in SSMS or SQLCMD or whatever and own your server. So all of the complicated parsing logic really hasn't slowed down an attacker at all.
These reasons are (among others) why GRANT, DENY and so on exist in SQL Server in the first place. They are good (mature, well-tested, easy-to-use) tools that are implemented in the correct place in the stack.
Create a database user with only select grants, and use this user for the connection, and then handle database SqlException when executing the command.

Using a database in a Windows application

I am developing a Microsoft Kinect game (for Windows) using C# and I need a local database to store information about players and their progress as well as more detailed information on their points and accuracy. I have never used a database within a Windows application and I was looking for some advice on how to do so. I have been trying to use SQL Server because it lets me create a database within Visual Studio. I have been unable to find many resources on how to interact with the database from within the C# application.
I really know very little about SQL Server so I do not know if it is the right choice for what I need. Does anyone have a suggestion for what sort of database system to use? Can you point me in the direction of some good resources/examples on how to do what I need to do?
Thanks so much!
Edit: I should also mention that I do have experience working with SQL.
There are other, more portable, solutions such as SQLite and SQL Server Compact Edition which do not require a separate server installation and are more easily accessed and distributed from within a standalone desktop application.
The usage can be largely compared to an external SQL server and/or Linq to SQL so the actual implementation should not be that hard.
Some interesting links:
How to: Deploy a SQL Server Compact 4.0 Database with an Application
An Introduction to SQL Server Compact Edition
As mentioned in another comment, a simple serialized XML file might also be enough for your use. It's fast, easy and if you don't need to perform any actual database operations but simply save and load everything then it might be more efficient.
Look into using a SQLDatasource and relevant tutorials. This will give you an easy way to get up and running without an intimate knowledge of SQL. Once you have the datasource setup and 'bound' to your database, you can use this to connect your controls (grids,labels,textboxes ect.) to it.
Check this out:
http://www.youtube.com/watch?v=w34BDhDPEEQ
You don't want the fully fledged SQL Server. SQL Server Compact Edition is more appropriate, or there's also SQLite for a non-Microsoft option.
The easiest way to interact with a database from C# is Entity Framework, which ships with .NET 4.5 or is downloadable as a nuget package for .NET 3.5 and .NET 4.
A different, non-relational-database option would be DB4O.
You could use Entity Framework
var player = db.Players.Where(x => x.playerId = id);
var points = player.points;
points =+ 100;
db.SaveChanges();
You could also write CRUD operations against the tables if you don't want to use an ORM
Basicly you will have to make a database with a table, using the GUI of Visual Studio.
Then where necessary in the code, you will have to create a connection with the database using a connectionstring. Then you will have to insert an SQL command using the SQLCommand class and execute it. This requires some knowledge about the SQL syntax, but just search what kind of command you want specifically now and in time you will get the hang of it. Don't forget to close the connection to the database when you are ready with writing or reading data.
I hope this gives the main idea.
Edit: Oh and for this kind of database SQL Server Compact will be enough.

Is there a way to log/trace all SQL queries made from a WCF service?

I'm working on a WCF service and I'd like to be able to get a dump of all the SQL queries it makes while I'm running it locally.
Currently its executing sprocs through numerous spread out SqlCommand's so I'd like to just get a list of every query that is ran.
Is there any sort of tool or configuration that I can setup to log this information? Normally I would just use something like SQL Profiler but I'm looking for something to run from the WCF perspective since I'm hitting an Azure database and SQL Profilier won't work with Azure (afaik)
I'm not aware of a built in way of logging all sql code when using SqlCommand/SqlConnection.
I found this article on msdn: Data Access Tracing in SQL Server 2008 maybe it points you in the right direction.
A simpler but not very generic way i can imagine is to write a class that inherits from SqlCommand and delegates all methods to the real SqlCommand while adding some logging.
Yea along the lines of what Jan said I'm not aware of just a generic logger with SQlCommand/SQLConnections you can plug into but if you are generating your SQLCommands from a standardized place you could make use of
StatementCompletedEventHandler
And from there pass the commands text to some sort of general logger like log4net/Console.Write/or something from the MS Ent Lib
Probably not the simple solution you were hoping for :-) Ideally there'd be some logging class you could register in the config file but I'm not aware of anything like that either :-/

How to create a SQL Server database programmatically in C#

I want to create a program, that will use SQL Server 2008 database. During the first start, I would like to open a window, which let the user create a database. It will be simply, textboxes with name and ip of the database computer to set and button "Go".
Program will be in WPF .NET4. And database will be in local network.
Could you suggest me a good solution? Is it a good programming practice, to do that? Or maybe I should just attached a sql script?
I do some research, I found that article: http://www.codeproject.com/KB/tips/CreateSQLDV.aspx
But, first issue, in SQL Server 2008, there is no Microsoft.SqlServer.SmoEnum.dll. So, when I do similar "data create" window, but for SQL Server 2008 (using maybe different dlls) - It will not work for SQL Server 2005. And maybe will not work with other versions of SQL Server 2008 to? I don't know.. Example from codeproject looks good, but I'm not sure.
I would like to do a flexible program.
I would recommend not to actually programmatically create the database. As you mentioned - with different versions of SMO, this becomes a bit of a nightmare.
My approach would be this:
with your installation, ship a "default" empty database that has your base structure (all your tables and everything) and possibly also some basic lookup data in certain tables
when the user indicates he doesn't have an existing database for your application, copy the MDF/LDF/and possibly NDF files to the SQL Server data location
attach those database files programmatically to the SQL Server instance
That seems a nice cleaner and more flexible approach.
I would avoid SMO.
It depends a LOT on your audience and the control you have over the expected environment, but attaching pre-made databases, while a convenient option, can sometimes have issues - to start with it's a binary under source control, so you don't get diffs for free in your source control system. In addition, you're attaching a database with certain options and things which might not be appropriate for the specific target environment - SQL Server 2005, SQL Server 2008, SQL Server 2008 R2? Other than all that, it's a valid approach similar to the way one might deploy Access applications in the past.
In a less controlled environment, I would go with either generating a SQL script containing all the DDL (and DML for lookup tables) or providing a script, offering to run it automatically and also giving them the option of running it themselves with their own tools (if they have a DBA).
Now your script (or at least the template for the script or the code that generates the script) is under source control and can satisfy a DBA who wants to inspect it.
The database creation may not need to be a part of your code per se. Especially, if you only need to create the database once. I suggest an approach on which you create an installer either by using Windows Installer or Inno Setup (I prefer Inno Setup). With an installer you can prompt the user for their SQL server name and the login credentials for their administrative user. Then you can use those to run a SQL script containing your CREATE DATABASE and CREATE TABLE statements, etcetera. Hope this helps.

LINQ to SQL Cannot create database [Schema Permissions]

For some integration tests I want to use LINQ to SQL to drop/re-create the test database. I've had this working fine before, however in this project the database is split up into several schemas.
When I try to run the ctx.CreateDatabase() command I'm getting this exception:
The specified schema name "xyz" either
does not exist or you do not have
permission to use it.
The login I'm using to do this has the role dbcreator - Does it need further permissions? Surely a login with persmissions to create a database should be able to create everything contained in that database also?
Update:
Since it looks like there isn't a solution to this problem using LINQtoSQL, does anyone have recommendations of any similiar tools to generate a db that are preferably free? Ideally I don't want to have to muck about hand writing sql build scripts.
From what I've read, the CreateDatabase() method is limited in what it can reproduce of the original database. It won't recreate things like triggers and check constraints, and I'm guessing it doesn't create custom schemas either. You may want to look into creating the database using a SQL Server .mdf file instead to work around this issue. See this blog entry for more details on some of the limitations of CreateDatabase().
I generally do this sort of work in NAnt to create, initialize the database, create users, add logins, etc....and also roll back capabilities. I have written on this topic quite a bit if you are interested:
Build automation with NAnt
Continuous integration with CruiseControl.NET
I will have to see if I can get LINQ to SQL to work in the way you are trying to use it...that sounds like what we used to do with NHibernate.
The dbcreator fixed server role grants you the permission to create a database. If you create a database, you are the dbo of said database and as dbo you have absolute power in the database, includding the power to create, alter and drop any schema and any object contained in any schema.
the problem with LINQ's CreateDatabase() is not permission, is code quality. The generated SQL code simply does not create the needed schema, so the Create table statements fail because the schema does not exist.
Your best choice, if you can afford it, is to add a VSTS Database Edition GDR R2 project to your solution and declare all your database objects in the Database Edition project (part of your solution). You'll be also getting the added benefit of storing all your database objects in a proper source control solution. The output of the Database project would be a .dbschema file containing the definition of your database. At deployment time (test or real) you would run the VSDBCMD Deployment and Schema Import tool to import your .dbschema into the target server. The tool is capable of doing initial deployment of your schema, as well as further upgrades (deploy only differences). The VSDB solution would allow you to controll all your database objects: tables, indexes, views, schemas, field contraints, table constraints, triggers, procedures, users, permissions, logins etc etc. It really covers all the objects that can be defined in SQL Server.
Actually LINQ to SQL does support schemas, but not every Sql Server edition does. To enable CreateDatabase() to generate them the DataContext must be aware that the target database does support them. It can be done by setting the provider on the DataContext:
[Provider(typeof(Sql2008Provider))]
public class CustomDataContext : DataContext {
...
}
Your user also requires db_dlladmin for that database.
I would definately look at Entity Framework, which I am beginning to look into these days. It's an OR/M, and will most definately suit your needs, and alot more once the next version is released.
Entity Framework is also a brain-child of Microsoft and can be found here: http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx
One thing to remember between LINQ to SQL and LINQ to Entities is that you are programming against a model, and not the database.

Categories