Some stored procedures are not displayed - sql

I have a wired issue with some of the stored procedures on my database. Those are not displayed in object explorer. I tried using filter to search by name and still it not appears!!!
Thing is when I try to create those missing ones it says the stored procedure is already exists. And I tried altering the SP and it worked. But I cannot see those yet.
Any idea regarding this?

I've had this conundrum before and it was because I was actually trying to create the stored procedure in the master database. I believe by default, in SSMS, this database is selected by default.
If you are using SSMS, ensure that the database selected from the dropdown list (usually top left on the query window toolbar) is the correct database.

This could be due to a number of things, including but not limited to:
Is there another object, not a stored procedure, present with that name?
Is the procedure in an unanticipated schema? In SSMS, they are listed in schema-then-procedure name order
Do you have sufficient access rights to see the procedure? (Probably, but it has to be mentioned)
Has it been marked as an MS-shipped procedure? Those may not appear with user schemas
Another "probably not", are you sure you are looking at the right database?

Related

Creating a database view from a dynamic string (EXECUTE IMMEDIATE) in a PL/SQL package - Questions?

I want to create a dynamic view at runtime made up of string of columns and a where clause using EXECUTE IMMEDIATE on one database which will be queried on a second database using a db_link.
My question are the following.
The view will be queried on another database using a database_link do I need to also GRANT privileges to the view (i.e. PUBLIC) and the SYNONYM (as PUBLIC) at the same time (if at all)? or does this only need to be created once?
Can a package be INVALID if in the PL/SQL package there is a reference to an object on another database via a database link that doesn't exist, is INVALID or has changed in structure? Or does it compile regardless?
I'm assuming I would need "CREATE OR REPLACE VIEW" in the the EXECUTE IMMEDIATE string as the second time I run this process the view will already exist on the database?
Thanks Guys in advance for any feedback on this.
First of all, I'd suggest you not to do that. In Oracle, objects are created once and used any time you want. What benefit do you expect from creating a view dynamically? (I'm not saying that you must not do it, just suggesting to think it over).
Now, to answer your questions:
You don't need GRANT because - in order to create a database link, you already know remote database's username and password
If object in another database is invalid, then executing or compiling your procedure will fail
Yes, as without or replace Oracle will complain that object with that name already exists.

How do you save a CREATE VIEW statement?

EDIT: This question was based on the incorrect premise that SQL VIEWS were cleared from a database when the user that created them disconnects from the server. Leaving this question in existence in case others have that assumption.
I'm trying to use views in my database, but I'm running up against an inability to save the code as a SQL Server object for repeated use.
I tried saving CREATE VIEW statements as procedures and user defined functions, but as many have answered on stack overflow, CREATE PROCEDURE and CREATE FUNCTION are incompatible with CREATE VIEW due to the only one in batch issue.
Obviously I don't want to retype my CREATE VIEW statements every time, and I'd prefer not to have to load them from text files. I must be missing something here.
You don't really "save" CREATE/ALTER statements. The create or alter statement changes the structure of the database. You can use SSMS to generate the statement again later by right clicking on the view, and choosing Script as->Create. This inspects the structure of the database and generates the statement.
The problem with this approach is your database now consists of both a structure definition(DDL) as well as its contents, the data. If you dropped/created the database to clear its data, you'd also have lost the structure. So you always need a database hanging around for the structure and back it up to ensure you don't ever lose the DDL.
Personally I would use Database Projects as part of Visual Studio and SQL Server Data Tools. This allows you to keep each View, Table, etc. as separate files, and then update the database using schema compare. The main benefit being you can separate the definition of the database from the database itself, and also source control or backup the DDL files.
If you really want to, you could create a view in a proc like this:
CREATE PROCEDURE uspCreateView AS
EXEC('CREATE VIEW... ')
Though, you'll have to escape single quotes in your view code with ''
However, I have to agree with the other comments that this seems like a strange thing to do.
Some other thoughts:
You can use sp_helptext to get the code of an existing view:
sp_helptext '<your view name here>'
Also, INFORMATION_SCHEMA.VIEWS includes a VIEW_DEFINITION column with the same code:
SELECT * FROM INFORMATION_SCHEMA.VIEWS

Update audit database name in triggers and views of main database?

I have a a system with two databases, main database and audit database. A lot of the triggers and table views in the main database and audit database are referencing from one database to the other. No I needed to change both databases names but unfortunately they failed to work because they still have the old names in the code.
Is there a code to search and replace the old name used for referencing or in dependence?
Thank you,
You will have to manually fix the references but you can leverage some sql to find the offending objects.
select OBJECT_NAME(id) as ObjectName
, text as ObjectCode
from sys.syscomments
where text like '%YourReplacedDatabaseName%'
That will give you a list of functions, procedures, views etc that have the old database name in the code. You will however have to recompile each object after you have updated the code. You could probably utilize some dynamic sql around this to do it for you but I would be nervous about changes on that scale automatically.

Create a Synonym for a database / Change DB views point to

I know databases aren't supported by CREATE SYNONYM, but I'm looking to achieve the functionality this would provide.
We've got Database A which contains views to tables on Database B. The trouble is "Database B" isn't always called "Database B". We use database projects for deployments, which at the moment fall over with an "Invalid Object Name" error if there isn't a "Database B".
The workaround at the moment is to open up the .dbschema file and do a find and replace. I guess another option would be to create a load of table synonyms.
What's the best way of changing the database a number of views reference without changing each view individually?
Thanks
Synonyms are a good way to do this. You have to create the synonyms at the object level though (as you've discovered). An easy way to do this would be to write a script that runs through the list of tables in DatabaseB (from your example) and creates a synonym for each one in DatabaseA. Keep the name of the synonym the same so the code in your views doesn't have to change. For instance, you you have tbl_a, tbl_b, and tbl_c in DatabaseB, you'd want your script to eventually do the following:
create synonym [otherDb].[tbl_a] for [DatabaseB].[schemaB].[tbl_a]
create synonym [otherDb].[tbl_b] for [DatabaseB].[schemaB].[tbl_b]
create synonym [otherDb].[tbl_c] for [DatabaseB].[schemaB].[tbl_c]
Now, in your view code, you'll always use [otherDb].[tbl_a], [otherDb].[tbl_b], and [otherDb].[tbl_c]. Hope this makes sense.
Last year I helped my current client with the implementation of a very similar design. We wrote a set of functions and stored procedures which generate the views automatically. Whenever you need to change the target database it generates the code to drop and recreate all of the views.
The code wasn't too difficult. It just uses the system tables to generate view code. I also wrote a Powershell prototype that uses SMO to do the same thing. The key is to have it automated to the point of requiring a single call so that you can do it easily and accurately.
We also included an exception table that used a pattern match of tables to exclude from view generation. It included a schema column and a table name column, each of which accepted LIKE patterns, so you could put "my_schema" and "%" to exclude all tables in the my_schema schema.
One master stored procedure accepted a target database name and would generate the entire script. Once the script is generated you can run it in SSMS or have that part automated as well.
This whole thing would be even easier if you just wanted to generate synonyms. We were using views so that we could change column lists, etc. and have the view DB look different than the target DB where needed.

Sql Server modify select

I'm pretty sure there is no way, but i'm putting this out there for those expert beyond my knowledge.
What i am looking to do is to somehow alter SELECT statements before they are executed, at the database level. For a seriously pared-down example, i'd like to do something like the following... when someone executes the following SQL
SELECT * FROM users.MESSAGES
i'd like to catch it, before it executes, and alter the statement to something like
SELECT * FROM users.MESSAGES WHERE RECIPIENT = ORIGINAL_LOGIN()
allowing me to enforce user limitations on the data in a fashion similar to ORACLE's VPDs, without needing to resort to creating views on top of all my tables that might need this.
Look into using a VIEW.
Sadly, this is not possible.
Even the Microsoft SQL Server row-level security features (e.g. in the security catalogs) are implemented using views.
So, if you really need the feature, you're going to have to set up views with SUSER_NAME() or some similar individual- or role-identifier in the WHERE clauses.
Sorry!
Use views (or inline table-valued functions), generate the views automatically and remove rights from the tables.
There used to be a round-about unethical way in SQL 2000. You could create a trigger on master..sysprocesses table for INSERT and do this kind of manipulation. Thankfully, this is not possible, at least AFAIK, in SQL 2005, as master..sysprocesses is a fake table.
For the benefit of some of US still using SQL 2000, here is how to do this in SQL 2000:
In the console right click on
servername
In the properties go to server
settings tab
Then check allow modifications to be
made directly to the system catalogs
checkbox.
Selected the sysprocesses table in
sysobjects and change it's xtype
from S(system) to U(user)
Now go to Master DB, tables - right
click on sysprocesses-All
tasks-Manage Triggers
Then you can write your trigger
After you are done, turn back
everything to it's original state.
Even with all of this, I still doubt if you can change the Select statement.
Raj
Disclaimer: Try this at your own risk. Be warned that you are making changes to system objects which could lead to undesirable results.
First, grant no direct table access to the users so they can't see the data from an ad hoc query. Make them use a stored proc to access the table and one of the parameters of the proc is the user login. Then write the code so that it only selects records for that login.