CTE and tablename as parameter - sql-server-2008

In SQL Server 2008, I have stored procedure containing a CTE
;with t1 as (select * from db..tablename where …)
Select * from t1;
I want to use tablename as one of the stored procedure parameters.
Please note the size of T1 turns out to be too big to use something like
Exec(‘select * into #temptable from db..’+’tablename’+’ where …’)
There have been similar questions and answers but none of them seems to help.
Thanks

I love using CTE's. They are such a great utility!
For this particular problem might I suggest against it. Given that you are "transporting" a table worth of data to another stored proc I think you should handle it a bit differently.
Consider your first proc:
IF OBJECT_ID('SomeTempTable') IS NOT NULL DROP SomeTempTable;
SELECT
*
INTO SomeTempTable
FROM
YourOtherTable
EXEC YourSecondProcedureName
Please note you'll need to be mindfull of the scope you want for your table. I haven't included working code until you make that consideration. More information can be found here: Temp Table Scope
Also note that the "YourSecondProcedureName" does not take a table value now. Instead (and with the right scope) you can just call out of your temp table by name. Its also considered best practice to drop your temp tables when done though there are some mechanisms in sql server depending on version that can do some of it for you. Again scope scope scope.
Hope this helps!
Matt

Related

Microsoft MS SQL System Tables

How I see into MsSql sys.sysprocesses
can I modify it?
Example :
select count(spid) from master.dbo.sysprocesses
The result will be what I want
As Dan has stated, sys schema objects cannot be modified, you will get an error if you try to do so.
The sys.sysproccesses view can be queried using the statement you have posted from a query window and will return results
select count(spid) from master.dbo.sysprocesses
If you are really wanting to "modify" which I assume means you want to update values, drop rows and such, you can add to a temp table and modify that but the data is a copy so anything you do will not affect the underlying view
SELECT *
INTO #MyTable
FROM sys.sysprocesses
sysprocesses is a view and a legacy one at that. One cannot modify system objects.
You can create your own view to encapsulate DMV queries:
CREATE VIEW dbo.YourView
SELECT COUNT(session_id) AS SessionCount
FROM sys.dm_exec_sessions;
GO

Can I check if a table exists before join?

I have the following problem. I have Table A and would like to join to table B if table B exists. Can this be done? I am only writing SQL in WorkBench to try achieve it.
I am aware I cannot use the EXISTS option as I have tried typing it out but it prompts for an error.
Any suggestions would be greatly appreciated.
Thanks.
I managed to do this using EXECUTE, so using a query that is only prepared at runtime:
SET #sqlCommand = IF(
EXISTS (SELECT column_name FROM information_schema.columns WHERE table_schema = '{{yourschemaname}}' AND table_name = '{{yourtablename}}' AND column_name = '{{yourcolumnname}}'),
'SELECT \'Yes! Good to go!\' as ColumnExists',
'SELECT \'Nope!\' as ColumnExists');
PREPARE executable FROM #sqlCommand;
EXECUTE executable;
Note that the two selects at the center (Yes!/No!) are the custom statements that are to be executed conditionally. So if the column exists, the first command is executed (select 'yes!'), otherwise the second one (select 'nope').
I got the hint from this discussion here.. have a look if you're looking for the MSSQL equivalent: https://ask.sqlservercentral.com/questions/97579/check-if-table-exists-in-join.html
Data manipulation language statements are typically written for a specific schema; you are assumed to know what the schema looks like when you issue the statement. So you don't generally have the capacity to ask whether a particular schema object exists or has a particular structure. You could however write a stored procedure that did different things depending upon the schema. You have the ability in a stored procedure to use conditional statements and to look in INFORMATION_SCHEMA.

Parameter sniffing on table valued parameters

I'm fairly certain that adding parameter sniffing to table valued parameters is of little or no value however I was wondering if someone could confirm this?
(INT_LIST is a user defined table type which is a single column of type INT)
CREATE PROCEDURE [dbo].[TVPSniffTest](
#param1 varchar(50),
#idList INT_LIST readonly
)
AS
BEGIN
DECLARE #param1_sniff VARCHAR(50) = #param1 --this is worth doing
DECLARE #idList_sniff INT_LIST
INSERT INTO #idList_sniff SELECT value FROM #idList --will this help?
--query code here
END
As Jeroen already mentioned, there is no parameter sniffing issue with TVPs. And also that one option to mitigate the lack of statistics is to copy the TVP to a local temp table (which does maintain statistics).
But, another option that is sometimes more efficient is to do a statement-level recompile on any queries using the table variable (i.e. the TVP). The statistics won't be maintained across queries so it needs to be done on any query that involves the table variable that is not something like a simple SELECT.
The following illustrates this behavior:
DECLARE #TableVariable TABLE (Col1 INT NOT NULL);
INSERT INTO #TableVariable (Col1)
SELECT so.[object_id]
FROM [master].[sys].[objects] so;
-- Control-M to turn on "Include Actual Execution Plan".
-- For each of the 3 following queries, hover over the "Table Scan"
-- operator to see the "Estimated Number of Rows".
SELECT * FROM #TableVariable; -- Estimated Number of Rows = 1 (incorrect)
SELECT * FROM #TableVariable
OPTION (RECOMPILE); -- Estimated Number of Rows = 91 (correct)
SELECT * FROM #TableVariable; -- Estimated Number of Rows = 1 (back to incorrect)
This has no effect whatsoever -- in fact, it's detrimental to performance because you're copying the whole table first.
The optimizer maintains no statistics for either table-valued parameters or table variables. This can easily lead to bad query plans with cardinality mismatches; the solution for that is usually an intermediate temp table. In any case, parameter sniffing won't be an issue -- the table contents are never used to optimize the query plan.
Incidentally, while you can assign the parameter to a local variable to circumvent sniffing, a more flexible option is to use the OPTIMIZE FOR or RECOMPILE hints in queries that are particularly affected (or WITH RECOMPILE on the whole stored procedure, but that's a little more drastic). This prevents cluttering the procedure with copies of everything.

Is it possible a trigger on a select statement with MySQL?

I know that triggers can be used on insert, update and delete, but what about a trigger (or sort of) on a select statement. I want to use a trigger to insert data on a table B when it is selected an existent record on a table A, it could be possible?.
Thanks in advance.
You should design your application so that database access occurs only through certain methods, and in those methods, add the monitoring you need.
Not exactly a trigger, but you can:
CREATE FUNCTION myFunc(...) BEGIN INSERT INTO myTable VALUES(...) END;
And then
SELECT myFunc(...), ... FROM otherTable WHERE id = 1;
Not an elegant solution, though.
It is not possible in the database itself.
However there are monitoring/instrumentation products for databases (e.g. for Sybase - not sure about MySQL) which track every query executed by the server, and can do anything based on that - usually store the query log into a data warehouse for later analysis, but they can just as well insert a record into table B for you, I would guess.
You can write an application which will be monitoring the query log and doing something when a select occurs. A pretty crude way to solve the problem though...

MySQL 1443: what does it mean?

I'm trying to do an update, in MySQL 5.0, of the form:
update mytable.myfield t
set f = 'blah'
where t.id in (select v.id from myview v where ...);
MySQL tells me:
ErrorNr. 1443
The definition of table 'v' prevents operation UPDATE on table 't'.
The MySQL docs list this error, but (as usual) don't say what it means. Can anyone shed some light on this for me? I only reference the view in the subquery, and I only reference the table in the main query, and I don't know why these would prevent the update. The only thing I found with google is a bug in the MySQL bug db related to triggers, but (AFAIK) there are no triggers in my db.
I think the view myview must be based on the table mytable, so that as it makes changes to myfield, it loses track of what's in the view and therefore makes for an illegal update.
I would recommend looking at the definition of myview, so that you can write your query without referencing it. Then you may be able to work it out.
Alternatively, dump the list of ids to a temporary table and use that for your subquery.
Rob