Best Practice - Handling multiple fields, user roles, and one stored procedure - c#

I have multiple fields both asp:DropDownList's and asp:TextBox's. I also have a number of user roles that change the Visible property of certain controls so the user cannot edit them. All of this data is saved with a stored procedure call on PostBack. The problem is when I send in the parameters and the control was not on the page obviously there wasn't a value for it, so in the stored procedure I have the parameters initialized to null. However, then the previous value that was in the database that I didn't want changed is overwritten with null.
This seems to be a pretty common problem, but I didn't have a good way of explaining it. So my question is, how should I go about keeping some fields from being on the page but also keeping the values in the database all with one stored procedure?

Apply the same logic when chosing what data to update as the logic you're actually using when chosing what data (and its associated UI) to render.

I think the problem is you want to do the update of all fields in a single SQL update, regardless of their value.
I think you should do some sanity check of your input before your update, even if that implies doing individual updates for certain parameters.

Without an example, it is a little difficult to know your exact circumstances, but here is a fictitious statement that will hopefully give you some ideas. It is using t-sql (MS SQL Server) since you did not mention a specific version of SQL:
UPDATE SomeImaginaryTable
SET FakeMoneyColumn = COALESCE(#FakeMoneyValue, FakeMoneyColumn)
WHERE FakeRowID = #FakeRowID
This basically updates a column to the parameter value, unless the parameter is null, in which case it uses the columns existing value.

Generally to overcome this in my update function
I would load the current values for the user
Replacing any loaded values with the newly changed values from the form
Update in db.
This way I have all the current plus everything that has been changed will get changed.
This logic will also work for an add form because all the fields would be null then get replaced with a new value before being sent to the db. You would of course just have to check whether to do an insert or update.

Related

SQL Server prevent only specific table from updating based on parameter passed from C# controller

In our .net application, we have a tool that allows you to type SQL in a browser and submit it, for testing. In this context, though, I need to be able to prevent testers from writing to specific tables. So, based on the parameter passed from the controller (InSupportTool = true, or something), I need to know if SQL Server is allowed to make updates or inserts to, say, an accounts table.
Things I've tried so far:
I have tried looking into triggers, but there is no before trigger available, and I've heard people don't recommend using them if you can help it.
Parsing the passed SQL string to look for references to inserting or updating on that table. This is even more fragile and has countless ways, I'm sure, of getting around it if someone wanted to.
Check constraint, which is the closest I feel I've gotten but I can't quite put it together.
For check constraints, I have this:
ALTER TABLE Accounts WITH NOCHECK
ADD CONSTRAINT chk_read_only_accounts CHECK(*somehow this needs to be dynamic based on parameters passed from C# controller*)
The above works to prevent updates to that table, but only if I put a check like 1 = 0. I've seen a post where people said you could use a function as the check, and pass parameters that way, but I'm at the limit of my familiarity with SQL/.net.
Given what I'm looking to do, does anyone have experience with something like this? Thanks!
Since the application is running under a different account than the end user, you could specify your application name in the connection string (e.g. Application Name=SupportTool) and check that in an after trigger, rolling back the transaction as needed:
CREATE TABLE dbo.example(
col1 int
);
GO
CREATE TRIGGER tr_example
ON dbo.example
AFTER INSERT, UPDATE, DELETE
AS
IF APP_NAME() = N'SupportTool'
BEGIN
ROLLBACK;
THROW 50000, 'This update is not allowed using the support tool', 1;
END;
GO
INSERT INTO dbo.example VALUES(1);
GO

How to query an SQLite db in batches

I am using C# with .NET 4.5. I am making a scraper which collects specific data. Each time a value is scraped, I need to make sure it hasn't already been added to the SQLite db.
To do this, I am making a call each time a value is scraped to query against the db to check if it contains the value, and if not, I make another call to insert the value into the db.
Since I am scraping multiple values per second, this gets to be very IO-intensive, with constant calls to the db.
My question is, is there any better way to do this? Perhaps I could queue the values scraped and then run a batch query at once? Is that possible?
I see three approaches:
Use INSERT OR IGNORE, which will reject an entry if it is already present (based on primary key and unique fields). Or plainly INSERT (or its equivalent (INSERT or ABORT) which will return SQLITE_CONSTRAINT, a value you will have to catch and manage if you want to count failed insertions.
Accumulate, outside the database, the updates you want to make. When you have accumulated enough/all, start a transaction (BEGIN;), do your insertions (you can use INSERT OR IGNORE here as well), commit the transaction (COMMIT;)
You could pre-fetch a list of items you already have, depending, and check against that list, if your data model allows it.

Stored procedure validation best approach

Alright so I have a user table that I would like to check against. This user table has a username, email, and accountnumber. Would I would like to do is check if anyone of those has been taken and if it has return if it has been taken.
I was thinking about doing an array example
CHECK AGAINST TABLE
IF USERNAME MATCHES INSERT #ARRAY "TRUE"
IF EMAIL MATCHES INSERT #ARRAY "TRUE"
ETC.
Then on the C# side I will call the array and check by index
If registrationValidationArray[0] = "true"
{
ViewBag.UserNameTaken = "True"
return view("Registration")
// On cshtml post error next to username that it has been taken
}
So my question is does this approach sound logical and sound like it will work or is there another approach that might help me here procedure wise. Another developer suggested an incremental for the procedure so if username is taken +1 and then on the C# side display according to the numeric value but I couldn't wrap my head around that one. Anyone know of a better way or see a flaw in my logic?
If you are using the Telerik OpenAccess ORM and you have a stored procedure returning the details from the check I would suggest you to map this stored procedure to a Domain Method, then OpenAccess will return you an object with nicely named properties. You can use the returned object instead of the array. This will make you code more readable and easier to maintain. Now you should remember what means index 0 and index 1, even if you define the indexes as constants it will not be an eye-catching code.

Converting logic of DateTime.FromBinary method in TSQL query

I have a table that contain column with VARBINARY(MAX) data type. That column represents different values for different types in my c# DB layer class. It can be: int, string and datetime. Now I need to convert that one column into three by it's type. So values with int type go to new column ObjectIntValue and so on for every new column.
But I have a problems with transmitting data to datetime column, because the old column contains datetime value as a long received from C# DateTime.ToBinary method while data saving.
I should make that in TSQL and can't using .NET for convert that value in new column. Have you any ideas?
Thanks for any advice!
Using CLR in T_SQl
Basically you use Create Assembly to register the dll with your function(s) in it,
Then create a user defined function to call it, then you can use it.
There's several rules depending on what you want to do, but as basically you only want DateTime.FromBinary(), shouldn't be too hard to figure out.
Never done it myself, but these guys seem to know what they are talking about
CLR in TSQL tutorial
This is a one off convert right? Your response to #schglurps is a bit of a concern.
If I get you there would have to be break in your update script, ie the one you have woukld work up to when you implement this chnage, then you's have a one off procedure for this manouevre, then you would be updating from a new version.
If you want to validate it, just check for the existnec or non-existance of the new columns.
Other option would be to write a wee application that filled in the new columns from the old one and invoke it. Ugh...
If this isn't one off and you want to keep and maintain the old column, then you have problems.

How do I determine if a record already exists in a DataTable?

I have a DataTable that I am binding it to a GridView on my ASP.NET page. I also allow editing and insertion.
Upon saving/insertion, I need to determine if there is a duplicate description in the Gridview.
How can I accomplish this?
Any way the data which you are binding will have the unique id.
So after binding check for that id whether it is there or not in datatable.We can't say more than this unless you explain it more.
We may need some more information on what kind of database you are using to give you the right answer, but I'll take a swing anyway.
First, you need to have a PRIMARY KEY on your database table for several reasons including a default index and insuring uniqueness. Second, you can configure the table to have a UNIQUE INDEX on the description column. This will prevent the insertion of duplicate data at the database level. But, once you do that you will likely get some kind of exception or error in your client application that you will need to catch and handle.
Also, you could create an AJAX function to filter the data as the user types in the new row and show them records that are similar. I did this on an app where the users would put in the same request but use slightly different wording.

Categories

Resources