I have few SQL scripts which setups the db of an app. have few scripts creating packages which has few references of views, and similarly have scripts for creating views which has references of packages.
Is there a way to separate these two scripts which would then individually create only packages or views respectively.
Or any alternate to work on this.
First, create the package specifications.
Second, create the views -- they reference the specification, not the body.
Third, create the package bodies -- they reference the views.
You could just create all your views first using the syntax
CREATE OR REPLACE FORCE VIEW
which creates a view even if the referenced objects don't exist yet, then create all your package specs, then the bodies.
Now you could compile all invalid objects or just let Oracle take care of it (see this link)
Ask Tom - "invalid objects"
I think you have to calculate the reference graph manually and then order the execution of the scripts accordingly.
So you need to create a set of scripts views1.sql, views2.sql, ... and packages1.sql, packages2.sql, ...
Views1.sql contains only views that are not referencing any packages.
Packages1.sql contains only packages that are not referencing any views.
Views2.sql contains only views that are referencing packages from packages1.sql.
Packages2.sql contains only packages that are referencing views from views1.sql.
And so on until you are finished.
Related
We have a bunch of views in postgres that are created as repeatable migrations by Flyway.
The error that we have encountered is that if we want to rename a column by using CREATE OR REPLACE VIEW, postgres throws an error and cannot do so.
One option is to drop the view first. But this causes a problem if something else depends on the view, which will also throw an error.
Is there any way of dealing with this without having to write complicated scripts to drop any tables/views that depend on this view as that will also require recreating the other views. This process can get very messy and wondering if there is a more elegant solution?
You cannot use CREATE OR REPLACE for it because it was designed to extend column list:
CREATE VIEW
CREATE OR REPLACE VIEW is similar, but if a view of the same name already exists, it is replaced. The new query must generate the same columns that were generated by the existing view query (that is, the same column names in the same order and with the same data types), but it may add additional columns to the end of the list. The calculations giving rise to the output columns may be completely different.
Options:
make changes that are backward compatible i.e. only adding new columns
drop and recreate view(you need to handle the object dependencies)
Flyway is migration-based tool, you could search for "state-based" migration tool for PostgreSQL(SQL Server has SSDT). Related State- or migrations-based database development
6 Version Control tools for PostgreSQL
State-based tools - generate the scripts for database upgrade by comparing database structure to the model (etalon).
Migration-based tools - help/assist creation of migration scripts for moving database from one version to next.
I am trying to create a solution for a web application (that also contains the database as a database project) and then deploy it from TFS using web deploy for the application and DACPAC for the SQL database.
Unfortunately the database is referencing another database using 3-part names:
Select * From Database1.dbo.Table1
This forces me to import the referenced database as a project in the solution for the application that references it and set it as a reference in the other project, as seen in the picture below:
The problem is that Database1 is referencing Database2, but Database2 is also referencing Database1.
However when I try to do this I get the following error:
I have searched online for a solution and found two:
1) Using composite projects to create another 3rd project that contains the references between the two databases and then make this project reference the other two.
See this link: Composite projects solution
2) Replacing all the 3-part names queries to dynamic SQL, such as this:
EXEC('Select * From Database1.dbo.Table1')
None of this solutions is good for me as I don't just have two databases referencing each other, but many databases referencing a central database that references them back, as seen in the schema below:
The first solution would require that I import all the databases into the solution of each application (as they are linked to each other via the Central Database). Also there would be the circular reference error for each pair of projects (Database, Central Database).
The second solution would work as the queries would be seen as strings and would not require me to reference the Central Database in the solution, however I do not like the idea of having so many dynamic queries. Also it would be way to much work to replace all queries with dynamic SQL in each application database.
I would like to know if there are any other solutions beside the two I have mentioned.
The right way to solve the circular references problem is using the composite projects.
In general the "trick" consists to isolate all the shared objects (and the ones referenced by these; eg. a shared view and all the tables/functions used in its definition) in a composite project for each database.
In this way each database will be defined by a couple of database projects: one containing the objects used only inside it (base) and one containing all the objects to be shared with the other databases (shared).
Then you have to link a base database project with the shared one whose object are needed in its definitions.
One picture is worth a thousand words:
The dashed lines represent the "Same database" references (composite project). The solid ones are "regular" references.
I've updated my blog post with a generic case:
SSDT: How to Solve the Circular References Issue
You can also create a dacpac out of the existing database and add that dacpac as the database reference. We did that using a "Schema" folder to store all of the dacpacs and updated/referenced those as needed.
http://schottsql.blogspot.com/2012/10/ssdt-external-database-references.html
You can create another project that can be referenced Database1 and Database2 and this project handle calling between the two projects.
and let this project communicate with web application.
I'm working on a AS400 database and I need to manipulate library/collection with sql.
I need to recreate something similar to the CLRLIB command but I don't find a good way to do this.
Is there a way to delete all the table from a library with a sql query ?
Maybe I can drop the collection and create a new one with the same name. But I don't know if this is a good way to clear the library.
RESOLVE :
Thanks to Buck Calabro for his solution.
I use the following query to call the CLRLIB in SQL :
CALL QSYS.QCMDEXC('CLRLIB LIB_NAME ASPDEV(ASP_NAME)', 0000000032.00000)
Where LIB_NAME is the name of the library I want to clear, ASP_NAME is the name of the ASP where the library is and 0000000032.00000 is the command lenght.
(note that the term COLLECTION has been deprecated, SCHEMA is the current term)
Since a library can contain both SQL and non-SQL objects, there's no SQL way to delete every possible object type.
Dropping the schema and recreating it might work. But note that if the library is in a job's library list, it will have a lock on it and you will not be able to drop it. Also, unless the library was originally created via CREATE SCHEMA (or CREATE COLLECTION) you're going to end up with differences.
CRTLIB creates an empty library, CREATE SCHEMA creates a library plus objects needed for automatic journaling and a dozen or so SQL system views.
Read Charles' answer - there may be objects in your schema that you want to keep (data areas, programs, display and printer files, etc.) If the problem is to delete all of the tables so you can re-build all of the tables, then look at the various system catalog tables: SYSTABLES, SYSVIEWS, SYSINDEXES, etc. The system catalog 'knows' about all of the SQL tables, indexes, views, stored procedures, triggers and so on. You could read the catalog and issue the appropriate SQL DROP statements.
We are developing an application which uses multiple schemas to manage database objects.
I cannot see anyway of doing this with Liquibase.
I had to drop schemas manually and create them.
dropAll gradle task only drops objects in public schema.
Any help would be great.
Thanks for your time.
Liquibase can handle objects within multiple schemas and can also manage creating additional schemas as well.
When you connect to the database, Liquibase will create a DATABASECHANGELOG table in the default schema and that schema needs to exist. That table tracks which changeSets have executed, and anything that can be done through SQL can be done within your changeSets.
There are built-in tags for things like createTable, addColumn etc which will make changes in the default schema, but they all have tags such as tableSchemaName that can be used to target the object to a different schema.
If you want to make changes for which there are not built-in tags, you can always use the "sql" tag and specify whatever sql you want, such as create database additional_info
Is their any way to ignore the dependencies while creating the database objects?
for example, i want to create a function on the database that uses the table(s), but i want this function to be created before creating the tables.
I do not see any need for this. Do you see an advantage in doing this?
In oracle, you can create a function or package or procedure without the dependent objects present in the database but when you compile it says compiled with error and if you have to use them, then you have to re-compile the object again.