I'm working on a SQL Server 2005 database and I'm trying to pass a table variable from one stored procedure to another. Below is the structure of the table and my attempt.
#MyTable
EmployeeID FirstName LastName
1 Dummy Last
2 Some Name
I tried converting the table into XML and passing the XML as a parameter to the new SP.
SELECT * FROM #MyTable FOR XML AUTO
Result
<_x0040_MyTable EmployeeID="1" FirstName="Dummy" LastName="Last" />
<_x0040_MyTable EmployeeID="2" FirstName="Some" LastName="Name" />
But converting back from this XML to a table has become too complicated for my level of SQL knowledge. Am I on the right path? Is there an easy way?
Note - I have seen a few posts which suggests to use #temp tables and I would not prefer to use that solution. I would like to use the #MyTable parameter.
Erland Sommarskog is your friend here. The link below provides a table showing options. For SQL Server 2005, TVF aren't an option. You will likely need to use XML or a temp table to share the data. I know you say these two are the least desirable options for you, but for 2005, I think they are the most appropriate.
http://www.sommarskog.se/share_data.html
Related
I have a table in that table i'm inserting all my TableNames of that database.
Now I need to pass this table name to OLEDB source DYNAMICALLY from my main table one by one
Is this possible to to pass the table name as dynamically in OLEDB source.
I suspect you are then going to run some SQL against the stored table name?
You'll need to approach this differently and run what you are trying within a SQL task.
If not, give us some more information about exactly what you are trying to achieve.
I have the challenge of needing to audit data changes made by users of an MVC application.
Auditing creation and deletion of records is easy.
Updates is proving to be the problem.
I'm looking for a way to automate this, but the problem I have is that the application is using stored procedures to bring back EF "complex types".
These are then used to build a view model, and after postback, the controller receives a new view model built from the form values passed back from the view. Therefore the original values are no longer available.
Does anyone have any suggestions for a secure way to keep the original values so they can be compared with the updated values, so that changes can be stored?
(I appreciate I could go back to the database for these, but is not efficient, and I would have to retain all the parameters to remake the same call, and find a way to automate that part of the process).
Have you tried an Audit Trigger using the INSERTED and DELETED tables.
http://weblogs.asp.net/jgalloway/archive/2008/01/27/adding-simple-trigger-based-auditing-to-your-sql-server-database.aspx
OR
In your stored procedures for insert,delete,update you can make use FOR XML AUTO. To get the XML for the record and add it to an audit table.
http://www.a2zdotnet.com/View.aspx?Id=71
UPDATE A T-SQL example
BEGIN
-- these tables would be in your database
DECLARE #table TABLE(ID INT IDENTITY(1,1) PRIMARY KEY, STR VARCHAR(10), DT DATETIME)
DECLARE #audit_table TABLE(AuditXML XML, Type VARCHAR(10), Time DATETIME)
-- this is defined at the top of your stored procedure
DECLARE #temp_table TABLE(PK INT)
-- your stored procedure will add an OUTPUT to the temp table
INSERT INTO #table
OUTPUT inserted.ID INTO #temp_table
VALUES ('test1', GetDate()),
('test2', GetDate() + 2)
-- at the end of your stored procedure update your audit table
INSERT INTO #audit_table
VALUES(
(
SELECT *
FROM #table
WHERE ID IN (SELECT PK FROM #temp_table)
FOR XML AUTO
),
'INSERTION',
GETDATE()
)
-- your audit table will have the record data
SELECT * FROM #audit_table
END
In the example above you could make temp_table a clone of table (have all of the columns from table) and in your OUTPUT clause use INSERTED.* INTO #temp_table, this would avoid have to reselect the records before getting the FOR XML AUTO. Another note, for stored procedures that do DELETE you would use DELETED.* instead of INSERTED.* in your OUTPUT.
If using SQL Server I recommend that you look into Change Data Capture (CDC).
It's an out of the box solution for auditing changes to the underlying tables of your application and it's relatively straightforward to set up, so there is no need for a custom solution that you then have to maintain.
If you have any supporting applications for your site, they'll also be covered and it also has the benefit of auditing any changes made directly against the database, such as from a DBA running a script.
Since your asp.net application may be running under one particular account, you'll probably need to add additional tracking information to capture the user who made the change. Fortunately this is also relatively straightforward. The following Stack Overflow question covers an approach to this using the ObjectStateManager
I was lookging for this myself, found this, check out Tracker for EF
I am using stored procedure to extract data from two different databases to a ASP.NET application. My stored procedure work as follows
- Check if global temporary table exist or not say ##temp_table
- if exist then drop it and if not create new temporary table say ##temp_table
- Extract data from two different databases and fill it to Temporary table
- Select data from temporary table
- Drop temporary table
Now problem is that when number of users accessing the same page with same stored procedure as above then to some users it get error that temporary table already exist.
Now please some one help me to solve such problem or suggest me some alternate because I don't want to write query in side ASP code. Some one suggest me to use views. Waiting for your suggestions.
"##" tables are accessible by all connections to the SQL instance, while "#" tables are accessible only by the connection that created them. The functionality you are describing sounds like you should be using "#" tables, not "##" tables.
You must not create table, you must declare variable for temporary table storage...with the column you expect to fill out...declare table variable like this:
declare #tmpTable table(myID int,myName varchar(50));
fill it like
insert into #tmpTable
Select * from table1
use it like
select * from #tmpTable
I have an ASP.NET MVC Web Application that interacts with a SQL Server 2008 database via Entity Framework 4.0.
On a particular page, i call a stored procedure in order to pull back some results based on selections on the UI.
Now, the UI has around 20 different input selections, ranging from a textbox, dropdown list, checkboxes, etc.
Each of those inputs are "grouped" into logical sections.
Example:
Search box : "Foo"
Checkbox A1: ticked, Checkbox A2: unticked
Dropdown A: option 3 selected
Checkbox B1: ticked, Checkbox B2: ticked, Checkbox B3: unticked
So i need to call the SPROC like this:
exec SearchPage_FindResults #SearchQuery = 'Foo', #IncludeA1 = 1, #IncludeA2 = 0, #DropDownSelection = 3, #IncludeB1 = 1, #IncludeB2 = 1, #IncludeB3 = 0
The UI is not too important to this question - just wanted to give some perspective.
Essentially, i'm pulling back results for a search query, filtering these results based on a bunch of (optional) selections a user can filter on.
Now, My questions/queries:
What's the best way to pass these parameters to the stored procedure?
Are there any tricks/new ways (e.g SQL Server 2008) to do this? Special "table" parameters/arrays - can we pass through User-Defined-Types? Keep in mind im using Entity Framework 4.0 - but could always use classic ADO.NET for this if required.
What about XML? What are the serialization/de-serialization costs here? Is it worth it?
How about a parameter for each logical section? Comma-seperated perhaps? Just thinking out loud.
This page is particulary important from a user point of view, and needs to perform really well. The stored procedure is already heavy in logic, so i want to minimize the performance implications - so keep that in mind.
With that said - what is the best approach here?
By a quick Googling, it looks like Entity Framework doesn't support them, but you can use Table Valued Parameters in ADO.
You manage that by defining a table type in your server:
CREATE TYPE yourTypeName AS TABLE (
columnName <column type>
-- more columns if you wish, too
)
and then use it by making a SqlCommand, and doing this:
SqlParameter param = command.CreateParameter();
param.ParameterName = "#something"
param.SqlDbType = SqlDbType.Structured
param.Value = // a DataTable which matches your table type, I can stick in code I use if you like
param.TypeName = "table type name";
And your procedures will look like this:
CREATE PROCEDURE procName
#something yourTypeName READONLY
AS
BEGIN
...
Your SQL queries will then use that parameter as if it were a table, though it's read-only.
Performance-wise, I'm not a DBA, and I'm not sure how fast XML is - I gather it's pretty quick. TVPs though are rather blazingly fast, and even the relatively-simple DataTable method I've used runs great. There's more about TVPs here, and quite a few blog posts out there about SQL and TVPs in general.
Currently i am using sql encryption and would like to continue using it through Linq. I have all my CRUD stored proc's wired up to the table in order to handle the encryption/decryption on the backend. Problem is my database model see's a field type of varbinary(max) which is used for the sql encryption storage. The retrieval sp for this table does the decryption thus returning a string value. How does one get around this. Seems like the model needs to recognize a string in place of the varbinary but i am unsure of how to handle this.
Thanks in advance.
So change the table mapping to a view mapping in the database model?
Off the top of my head, some choices:
Edit the ssdl manually.
Make a view and map that (you don't need to actually use it for anything but mapping).