Getting different values from view - sql

I have a two tables and a view for them.
Having inline query
select * from View_tbl where sector = '04'
but when i creates stored procedure for this
create proc spTest
#sector varchar(2)
as
select * from View_tbl where sector = #sector
both returns dataset with different values.
SP Returns those columns too which are in Main tbl but not in view.
Any suggestions please

If the definition of your view has changed, you may need to recompile the stored procedure.
When you use select * in a stored procedure, this will get compiled down to an explicit list of columns. Subsequent changes to the view definition may not be reflected in the definition of the sp (depending on a few other factors and the version of SQL Server).
In general, I try to avoid select * in stored procedures and code the list of columns explicitly. This avoids the dependency on recompilation.
create proc spTest
#sector varchar(2)
as
select
col1,
col2,
col3
from
View_tbl
where
sector = #sector

My guess is that you have the SP in two places by accident (check Master) and it executing the SP in the wrong database maybe an old version of your sp is laying around...Maybe fully qualify your tables with Database as sort term test.

Related

SQL: temp table "invalid object name" after "USE" statement

I do not fully understand the "USE" statement in Transact-SQL and how it affects the scope of temp tables. I have a user-defined table type in one database but not another, and I've found I need to "USE" that database in order to define a table of that type. Earlier in the query, I define a temporary table. After the "USE" statement, SSMS does not recognize the temp table as a valid object name, however I can still query from it without error.
The skeleton of my SQL query is as follows:
USE MYDATABASE1
[... a bunch of code I did not write...]
SELECT * INTO #TEMP_TABLE FROM #SOME_EARLIER_TEMP_TABLE
USE MYDATABASE2
DECLARE #MYTABLE MyUserDefinedTableType -- this table type only exists in MYDATABASE2
INSERT INTO #MYTABLE(Col1, Col2)
SELECT Col1, Col2 FROM (SELECT * FROM MYDATABASE2.dbo.SOME_TABLE_VALUED_FUNCTION(param1, param2)) T
SELECT A.*, B.Col2
FROM #TEMP_TABLE A
CROSS APPLY DATABASE2.dbo.SOME_OTHER_TABLE_VALUED_FUNCTION(#MYTABLE, A.SomeColumn) B
In the last SELECT statement, SSMS has red squiggly lines under "A.*" and "#TEMP_TABLE", however there is no error running the query.
So my question is: am I doing something "wrong" even though my query still works? Assuming the initial "USE MYDATABASE1" is necessary, what is the correct way to switch databases while still having #TEMP_TABLE available as a valid object name? (Note that moving the definition of #TEMP_TABLE to after "USE MYDATABASE2" would just shift the problem to #SOME_EARLIER_TEMP_TABLE.)
In SQL USE basically tells the query which database is the "default" database.
Temp tables can play tricks on intellisense - unless they're explicitly defined using the CREATE TABLE #MyTempTable route, intellisense doesn't really know what to do with them a lot of the time. Don't worry though - temp tables are scoped to the query.
Although I do feel it's worth pointing out: while UDTs are database specific, you can create an assembly to use across databases

Conditionally using a SQL Temp Table throws errors

I have a (not normalized) legacy SQL database and am working on a task to gather code from one of several similar tables. I want to execute a lot of identical code against the #Temp table, but the tables it draws from are very dissimilar (with some columns being the same).
My code is:
IF #Variable = 'X'
BEGIN
SELECT * INTO #Temp FROM TABLE1 WHERE Condition1 = #Condition
END
IF #Variable = 'Y'
BEGIN
SELECT * INTO #Temp FROM TABLE2 WHERE Condition1 = #Condition
END
At this point, I execute some common code. There is quite a lot and I want to just use #Temp, not have another IF condition with the code copied in multiple times. I cannot really declare the table ahead of time (it is very wide - and they are not the same) and I cannot really normalize the DB (the legacy system is far to 'mature' and my time frame is far to small). Also, at the end of the query, the #Temp table is used for creating new rows back in the original table (so again, I cannot just declare the common parts).
At this point, I cannot make my stored proc because
There is already an object named '#Temp' in the database.
This error highlights the 2nd IF block. Adding a DROP TABLE #Temp in the IF block does not help either. So I'm having to offload the work in additional SPROCs or repeat the code in conditional statements. For readability, I don't like either of these options.
Any way to use #Temp within multiple IF blocks as above ( I really have more IF conditions, only 2 shown to give an idea of the issue).
Example SqlFiddle

SQL Server 2005 join a number of tables in a view when some may not exist

I need to create a view, however the data is generated from an application with its own db management for tables which based on column count can create over 7 SQL Server tables for one internal table definition.
The tables all end with ['m' & number], eg devicem1, devicem2 ... devicem10
They all contain logical_name as their primary key, but you can never rely on which table will hold any other column in the internal table!
I need to create a view that joins the tables together as just device so when the application changes it doesn't mess up any stored procs I want to create.
Based on this query:
CREATE VIEW device AS
SELECT *
FROM devicem1 m1, devicem2 m2, devicem3 m3, ... devicem10 m10
WHERE m1.logical_name = m2.logical_name
AND m1.logical_name = m3.logical_name
...
AND m1.logical_name = m10.logical_name
Is there some way to join ten tables where I can ignore the fact that devicem9 & devicem10 may not exist?
With regards to the requirements of a view. The tables referenced MUST exist when the view is created. The SQL engine isn't going to allow you to create a view referencing tables that don't exist.
Considering that a view is just a stored select statement, after it's created the tables can be deleted (as long as schema-binding isn't in play); however any time you call or use the view all referenced tables must exist or it will toss an error.
Also, you CAN change the schema of referenced tables as long as it doesn't remove any fields specifically used in the view but again, if a specific column used by the view is missing any query using the view will fail.
You might have more luck getting away with what your trying to do with some creative table valued functions and dynamic sql. A table valued function is basically just a view that allows parameters and extended logic.
All in all, I would say what your describing sounds a little sketchy though.
I would periodically recreate the view based on the tables that are available.
So, if the application runs every night to create the tables, then after the app runs, check which tables are available and recreate the views.
In the end, you will have to use dynamic sql, doing something like:
declare #sql varchar(max);
select #sql = (select '(select * from '+table_name+') union all'
from information_schema.tables
for xml path (''));
set #sql = left(#sql, len(#sql) - 10);
set #sql = 'create view <whatever> as '+#sql;
exec(#sql);

How to SELECT [temp table1] = [subselect 1], [temp table2] = [subselect 2] FROM [Stored Procedure]

I have a stored procedure that returns two selects, which I use in a report.
The first select is data to display in tabular format and the second are metadata to display in the report head, like showed below:
CREATE PROCEDURE dbo. GetReport
#Input INT
AS
BEGIN
--Get #Metadata
-- #Results = f(#Metadata) … compex calculation
SELECT * FROM #Results
SELECT * FROM #Metadata
END
As the sproc calculation is quite intensive, I would like to prepare the report lines as plain data (in two tables: PrecalcResults and PrecalcMetadata) for some mostly used sproc parameters overnight.
Lather I would directly select the precalculated vaues or calculate them with the sproc according to the parameters.
For maintenance reasons I would like to use the same sproc to calculate data that would be:
1. showed in the report
2. be stored in PrecalcResults and PrecalcMetadata (with the used parameters)
If I would have single select sproc I would an approach desctibed here:
Insert results of a stored procedure into a temporary table
As I have multiselect sproc I would like to do something like above but with two tables.
In .net I would do DataSet.Tables[0] and DataSet.Tables[1]..., but I want to do it in tsql, to run it in daily job.
Is this even possible in MS SQL?
I have to apologize myself, from the answer below I can see I was not very clear.
I would like to do implement this functionality as pure TSQL.
Yes, this is possible.
It's perfectly fine to return multiple result sets from a single stored procedure as you have suggested.
Your only potential issue is the limitation of a TableAdapter being able to pull both result sets from the stored procedure, but there's a very simple work-around for that issue.

SQL stored procedure combine result

I have written two SQL Server stored procedures
For example:
create PROCEDURE query1
AS
SQL code here...
create PROCEDURE query2
AS
SQL code here...
Now I can call them individually using the following command, and the returned value is the following.
exec query1
Study availability
ACR 99.97%
Now I want to combine these stored procedures and get the results in one shot, like :
exec query1
exec query2
and it give result something like following but somehow its now working its giving me syntax error. How do I combine two stored procedures and get results in one report?
This is T-SQL query
Study availability
ACR 99.97%
FOS 87.88%
You can't call them the way you describe (ie exec query1 exec query2). Here is one alternative assuming each proc returns a single value:
declare #result as table (
ACR float,
FOS float
)
INSERT INTO #result(ACR)
exec query1
INSERT INTO #result(FOS)
exec query2
SELECT ACR,FOS from #result
Since they both return the same column headings/data types I recommend combining the 2 separate queries into a single query and use UNION ALL.
EX:
SELECT 'ACR' AS Study,
SomeField AS Availability
FROM SomeTable1
UNION ALL
SELECT 'FOS' AS Study,
SomeField AS Availability
FROM SomeTable2;
It's hard to give more specific advice without seeing your actual Stored Procedures, but this is definitely much clearer than having 2 separate procedures. Hope this helps.
You can try that:
exec query1; exec query2
But be aware that the result is not combined, you just get the result of both SPs as separate result sets.
It depends on your code, you can insert the results of each SP into a table, and then UNION them together to get the single result set you are looking for - but this often can be slower if it's a lot of rows since you are making copies of the results instead of just streaming them out to the client. And it breaks the ability of the optimizer to combine things across the boundary, since it has to write them to the temporary tables.
If the procs aren't complex, I would consider making them into views or inline table-valued functions. These can be easily combined by other routines like views, functions or procedures and make things a bit more modular.