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

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.

Related

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

Binding error in MSSQL Views 'DWView.dbo.whatever'

I was given a database by a client. I can't access any of the data in the Views in this database because I get this error:
Invalid object name 'DWView.dbo.Person_C'.
I have no user/role/anything called DWView. The view exists, but nothing can access it. This happens in all of the views.
One thing I'm not clear on -- what is DWView.dbo? I know dbo is the schema/owner, but what about the DWView part? I've never encountered this in 15+ years of working with MSSQL databases.
Any attempt to access the views fails with that error, including sp_refreshview.
Is there anything I can do to remove this DWView thing? Thanks.
The error means the object doesn't exist. Like you mentioned, the schema comes before the view in syntax; so when you ask ...
One thing I'm not clear on -- what is DWView.dbo
... it means database.schema. So your query is looking for the database DWView, the schema dbo, and the object name Person_C.
As a note, if you're already on the database (USE Database GO), you don't have to use the database in your query; you can simply use SchemaName.ObjectName.
Try executing this ..
USE Your_Database_Name
GO
SELECT * FROM dbo.Person_C
GO
It should be [database].[schema].[objectname].

Check for Existing Saved Query in MS Access

I need to create a saved MS Access query from within my VB.net program using OleDb. But before I create the query I need to check and see if it already exists in the database. If it does exist I want to update it. How do I check for an existing query in MS Access using OleDb?
"If it does exist I want to update it."
Based on the comment discussion, I understand you will execute a statement on the OleDB connection to create the query. (In Access parlance, a QueryDef object.)
When the query does not already exist, the execute succeeds and you're done.
If the query does exist, the execute attempt will throw an error which you will trap in your VB.Net code. At that point, you want to revise the existing query. Unfortunately, I don't know any way to alter an existing query with OleDb. You can however discard the existing query and re-execute your statement to create the new version.
You can execute an Access DDL statement to discard the existing query. One of these two versions will do what you need:
DROP VIEW YourQueryNameHere;
DROP PROCEDURE YourQueryNameHere;
The first is for plain SELECT queries. The second is for what Access calls "action queries": INSERT; UPDATE; DELETE. A "make table" query (SELECT <field list> INTO NewTable FROM ...) also falls into the second (PROCEDURE) category as I recall (check to confirm if you need it). I think a SELECT query with PARAMETERS also falls into that second category (check if needed).
Note this is a only a suggested direction. I can't offer you VB.Net code. And I'm hopeful you know or can figure how to do the required error-handling in VB.Net.

Some stored procedures are not displayed

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?

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.