I am working on a SSIS package which checks the performance of stored procedures using extended events. We have an execute SQL task having a SQL query which is determined at run time as the arguments for those (Read) stored procedures are already hard coded and stored in a table.
Now, I need to run (write) stored procedures calls as well for which I can not hard code the arguments as they are (dynamically generated) dependent on output set of the previous stored procedures. Arguments and result set are not identical for each stored procedure and so the difficulty to use a single execute SQL task.
I thought of creating separate execute SQL task for each (write) stored procedure and add them to sequence container but that doesn't seem like a practical approach.
Can somebody suggest any approach to this problem?
Related
I was given the batch work to research our 200 stored procedures and find out a bunch of different information about them. Is there anyway in SQL Server 2012 to pull execution history on stored procedures? Also is there anyway to tell what application might be calling the stored procedure? Even an IP address would be helpful because we have several server that do various processing.
Any information you can provide me about this would be extremely helpful. I am relatively new to this type of thing in SQL. Thanks!
Is there anyway in SQL Server 2012 to pull execution history on stored procedures?
You can use sys.dm_exec_procedure_stats to find stored procedure execution times plus most time consuming, CPU intensive ones as well
SELECT TOP 10
d.object_id, d.database_id,
OBJECT_NAME(object_id, database_id) 'proc name',
d.cached_time, d.last_execution_time, d.total_elapsed_time,
d.total_elapsed_time/d.execution_count AS [avg_elapsed_time],
d.last_elapsed_time, d.execution_count
FROM
sys.dm_exec_procedure_stats AS d
ORDER BY
[total_worker_time] DESC;
Also is there anyway to tell what application might be calling the stored procedure? Even an IP address would be helpful because we have several server that do various processing.
The answer to both the above questions is NO, unless you monitor them real time using below query. You can run below query using SQL Server Agent as per your predefined intervals and capture the output in a table. Further please note that this gives you individual statements inside a stored procedure.
select
r.session_id,
s.login_name,
c.client_net_address,
s.host_name,
s.program_name,
st.text
from
sys.dm_exec_requests r
inner join
sys.dm_exec_sessions s on r.session_id = s.session_id
left join
sys.dm_exec_connections c on r.session_id = c.session_id
outer apply
sys.dm_exec_sql_text(r.sql_handle) st
(1) When you open multiple cursors in a stored procedure, and then use a JDBC callable statement to iterate through the result sets, each in turn, are the order in which they are returned the same order in which they cursors are opened in the stored procedure? Or reverse of that? Or....?
(2) Is there a way to specify by sequence number or name which result set to process first?
For 1: The order of returned resultsets is undefined for JDBC, so it will depend on your actual database system. That said, it would be highly illogical for a stored procedure to return results in a different order than the order they are produced by the stored procedure.
For 2: Once again, this is not defined by JDBC. However I haven't heard of database systems that would allow you to control the order of returned results by any means other than their order in the stored procedure.
I have this external oracle Stored Procedure which takes INTEGER,CLOB,VARCHAR as parameters, and which inserts a record to table upon executing. This will be called using a dao layer which consists of JAVA + Spring.
I have been asked to insert multiple records (1000s ) using the same procedure. so I am thinking of writing a pl/sql block which accepts either String or Clob and substrings the values in a loop which calls the procedure. For that I have to either append a String with delemeters for each record and pass it as a parameter or I could create a CLOB from that String and pass it as a parameter.
Eg:String param ="value1,value2,value3 | value1,value2,value3 | value1,value2,value3 ..etc"
My questions are:
Is there a better solution than what I am thinking (because I think it is better to loop it inside the DB server rather than looping in DAO layer and making 1000s of DB calls)?
If I go ahead with my solution will there be limitations which prevents my effort, such as size of the data that I can pass to the pl/sql block?
I would refer you to this SO question:
Bulk insert from Java into Oracle
Basically, you should be doing a few bulk operations rather than thousands of individual ones.
I'm using EF 4.1 (Code First). I need to add/update products in a database based on data from an Excel file. Discussing here, one way to achieve this is to use dbContext.Products.ToList() to force loading all products from the database then use db.Products.Local.FirstOrDefault(...) to check if product from Excel exists in database and proceed accordingly with an insert or add. This is only one round-trip.
Now, my problem is there are two many products in the database so it's not possible to load all products in memory. What's the way to achieve this without multiplying round-trips to the database. My understanding is that if I just do a search with db.Products.FirstOrDefault(...) for each excel product to process, this will perform a round-trip each time even if I issue the statement for the exact same product several times ! What's the purpose of the EF caching objects and returning the cached value if it goes to the database anyway !
There is actually no way to make this better. EF is not a good solution for this kind of tasks. You must know if product already exists in database to use correct operation so you always need to do additional query - you can group multiple products to single query using .Contains (like SQL IN) but that will solve only check problem. The worse problem is that each INSERT or UPDATE is executed in separate roundtrip as well and there is no way to solve this because EF doesn't support command batching.
Create stored procedure and pass information about product to that stored procedure. The stored procedure will perform insert or update based on the existence of the record in the database.
You can even use some more advanced features like table valued parameters to pass multiple records from excel into procedure with single call or import Excel to temporary table (for example with SSIS) and process them all directly on SQL server. As last you can use bulk insert to get all records to special import table and again process them with single stored procedures call.
Let's say I have 'myStoredProcedure' that takes in an Id as a parameter, and returns a table of information.
Is it possible to write a SQL statement similar to this?
SELECT
MyColumn
FROM
Table-ify('myStoredProcedure ' + #MyId) AS [MyTable]
I get the feeling that it's not, but it would be very beneficial in a scenario I have with legacy code & linked server tables
Thanks!
You can use a table value function in this way.
Here is a few tricks...
No it is not - at least not in any official or documented way - unless you change your stored procedure to a TVF.
But however there are ways (read) hacks to do it. All of them basically involved a linked server and using OpenQuery - for example seehere. Do however note that it is quite fragile as you need to hardcode the name of the server - so it can be problematic if you have multiple sql server instances with different name.
Here is a pretty good summary of the ways of sharing data between stored procedures http://www.sommarskog.se/share_data.html.
Basically it depends what you want to do. The most common ways are creating the temporary table prior to calling the stored procedure and having it fill it, or having one permanent table that the stored procedure dumps the data into which also contains the process id.
Table Valued functions have been mentioned, but there are a number of restrictions when you create a function as opposed to a stored procedure, so they may or may not be right for you. The link provides a good guide to what is available.
SQL Server 2005 and SQL Server 2008 change the options a bit. SQL Server 2005+ make working with XML much easier. So XML can be passed as an output variable and pretty easily "shredded" into a table using the XML functions nodes and value. I believe SQL 2008 allows table variables to be passed into stored procedures (although read only). Since you cited SQL 2000 the 2005+ enhancements don't apply to you, but I mentioned them for completeness.
Most likely you'll go with a table valued function, or creating the temporary table prior to calling the stored procedure and then having it populate that.
While working on the project, I used the following to insert the results of xp_readerrorlog (afaik, returns a table) into a temporary table created ahead of time.
INSERT INTO [tempdb].[dbo].[ErrorLogsTMP]
EXEC master.dbo.xp_readerrorlog
From the temporary table, select the columns you want.