I searched google but did not find any satisfying answer as to why I should use packages.
I know that a package is a bundle of procedures, functions and different variables. As I understand it sort of corresponds to object in OOP. But of course there's nothing like instantiating different instances of a package so that each instance would have different property values and behave differently.
Then what is the advantage of using packages when I can just create a standalone procedure and call it independently?
Packages provide the following advantages:
Cohesion: all the procedures and functions relating to a specfic sub-system are in one program unit. This is just good design practice but it's also easier to manage, e.g. in source control.
Constants, sub-types and other useful things: there's more to PL/SQL than stored procedures. Anything we can define in a package spec can be shared with other programs, for instance user-defined exceptions.
Overloading: the ability to define a procedure or function with the same name but different signatures.
Security: defining private procedures in the package body which can only be used by the package because they aren't exposed in the specification.
Sharing common code: another benefit of private procedures.
We only need to grant EXECUTE on a package rather than on several procedures.
As described in Oracle docs, packages are good because of:
modularity
easier application design
information hiding
added functionality
better performance
Details on each reason are explained in docs.
Related
I have a medium-sized app written in Ruby, which makes pretty heavy use of a RDBMS. As our code grows, I found the ugly SQL statements are spreading to all modules and methods in my app and embedded in many application logic. I am not sure if this is bad, however, my gut tells me this is quite ugly...
So generally in any languages, how do you manage your SQL statements? Or do you think it is harmful for maintainibility to let many SQL statements embedded in the application logic? Why or why not?
Thanks.
SQL is a language for accessing databases. Often, it gets confused as being the API into the data store for a larger application. In fact, you should design a real API between the data store and the app.
The means several things.
For accessing data stored in tables, you want to go through views in the database, rather than directly access the tables.
For data modification steps, you want to wrap insert/update/delete in stored procedures. This has secondary benefits, where you can handle constraints and triggers in the stored procedure and better log what is happening.
For security, you want to include database security as part of your security architecture. Giving all users full access may not be the best approach.
Unfortunately, it is easy to write a simple app that uses a database directly, whether in java or ruby or VBA or whatever. This grows into a bigger app, and then the maintenance problems arise.
I would suggest an incremental approach to fixing this. Go through the code and create views where you have nasty select statements. You'll probably find you need many fewer views than selects (the views can be re-used -- a good thing).
Find places where code is being modified, and change these to stored procedures. I always return status from the stored procedure for error checking and put log information into a table called someting like splog or _spcalls.
If you want to limit permissions for different users of your app, then you might be interested in this.
Leaving the raw SQL statements in the code is a problem. Just wait until you want to rename a column and you have to find all the places where this breaks the code.
Yes, this is not optimal - maintenance becomes a nightmare; it's hard to forecast and determine which code must change when underlying DB changes occur. This is why it is good practice to create a data access layer (DAL) to encapsulate CRUD operations from the application logic. There is often an business logic layer (BLL) between the application logic and DAL to enforce business rules/logic.
Google "data access layer" "business logic layer" and even "n-tier architecture" to learn more.
If you are concerned about the SQL statements littered around your application logic, maybe consider implementing them as Stored Procedures?
That way you will only be including the procedure name and any parameters that need to be passed to it in your code.
It has other benefits too, a common one being easier to re-use in multiple files.
There is much debate about speed and security of Stored Procedure and you will never get a definitive answer about that so I won't even open that can of worms.
Here is how you do this with Java: Create a class that encapsulates all access to the database. Add a method to the class for each query you need to run.
The answer for ruby will be similar to this.
It depends on the architecture of your application but a simple solution is to keep each sql in a file, qry.sql. For each Ruby module (or whatever is used in Ruby to aggregate related code) you can keep a folder SQL with these files. So, the collection of SQL folder/files form the data access layer of your application. The Ruby code provides the business layer. If your data model changes (field names, etc), you can do greps to identify the sql files that need changes. Anyway, definitely separate SQL from your logic code.
We have a number of modules within a larger suite that all use a common set of stored procedures and functions, due largely in part to the fact that they all use a common set of data and tables. This approach ensures that all modules receive the same answers for when making the same calls - a very good thing (especially in the financial industry)
However, the downside of this approach is that when we update one module in the suite that requires a change to one of the shared stored procedures or functions it requires that we update almost the entire suite. Which is a bad thing due to time and cost.
What kind of strategies can be employed to mitigate this suite upgrade issue every time we update a single stored procedure, while minimizing the management complexity.
This is similar somewhat to the version issue that Microsoft had with DLL(s) / API(s) where you would see a signature change on an API that would necessitate a xxx2 version, which is not ideal cause then you have basically two versions which both need to be maintained and upgraded with the potential that they get out of synch (i.e. two different answers for the same question).
Any strategies or best practices in this regard would be greatly appreciated.
Thanks in advance.
Whatty
Two strategies are views and stored procedures.
Use views to access the data in the tables. This way, you can change the underlying tables (for one module) and not have to change other modules immediately. Eventually, you can get around to changing that module as well. For instance, you might split one table into two different tables for one module. Other modules will never notice, because they access a view, and you just modify the view to return the original data.
Along these lines, you never want to use select *, because the columns, their names, or their ordering might change.
The second strategy is to wrap all insert, update, and delete into stored procedures. This has a second advantage that you can do checking, logging, and notifications in the procedure. You can try to mimic this with triggers and constraints, but I find the stored procedure approach much more maintainable.
I've asked about how to inject stored procedures support when working with Views in SQL Server.
How to use stored procedures in NHibernate for Create/Update when working with database view
Here's a piece of mapping file:
<sql-insert>
exec sp_cycle_insert ?,?,?
</sql-insert>
<sql-update>
exec sp_cycle_update ?,?,?,?,?,?
</sql-update>
<sql-delete>
raiserror ('Cycle can not be deleted', 10, 1)
</sql-delete>
So, I've done the refactoring, etc, and I run my tests.... All failed.
There reason is that SQL Server has view & stored procedures, whereas every time I run a test I set up database from scratch with:
new SchemaExport(configuration).Execute(false, true, false);
I thought about possible solution and here there are: is there a way to:
run additional scripts (I guess that is the solution) with stuff needed by database (like stored procedures, view etc)
On the other hand, running scripts can fail (currently I use sdf files, but what if I change to different provider in the future?). Also procedures/views use WITH construction as well as some SQL Server 2005 functions that can be not supported by database used during testing.
. So I though that it's time to mock repositories. But also here I see obstacles: views compute some readonly properties and NHibernate accesses backing fields using:
access="nosetter.camelcase"
If I switch to mocking the repository, I would be responsible for implementing view's logic in code. Are there any other solutions? Or I'm in big trouble!?
run additional scripts (I guess that is the solution) with stuff needed by database (likestored procedures, view etc)
Use IAuxiliaryDatabaseObject object(s) for this. It'll contain extra script to run when creating/dropping your schema using SchemaExport. This/these objects you pass in to your NH Configuration object (AddAuxiliaryDatabaseObject).
So I though that it's time to mock repositories. But also here I see obstacles: views compute some readonly properties and NHibernate accesses backing fields using
You should probably do both. Do integration tests against your real database to verify that your infrastructure/DAL/whatever-you-call-it layer works. In higher layers your probably want to write unit tests instead where things like repositories are mocked.
If I understand your question correctly you have problems setting up your test state because some data is private on your entities? That's not really an "issue" caused by NH/repos/data acess, but a general one. There are different ways to solve that, you can; relax your API to make it more testable, have an ctor accepting all data, use reflection one way or the other, let your entity's interface be readonly but its implementation have setters etc etc etc. It's hard to give general recommendation but try to find a way that suits your case.
I have several different packages, one for each logical part of my application. Some packages are getting huge but I would like to keep all the procedures/functions grouped in some way rather than breaking them into separate packages. Is there any way to nest, or namespace, my packages?
So if I have MYSCHEMA.PKG_PEOPLE and it has 10 procedures and 10 functions, is there no way that I can for instance move the CRUD procedures to MYSCHEMA.PKG_PEOPLE.CRUD. I want to keep all these items inside of PKG_PEOPLE but I want to further sub-divide them.
Beyond Schema and Package, there is no multi-level namespace handling for PL/SQL packages in Oracle.
Within a package body you can define nested procedures but I would guess this isn't what you need.
I think the closest you'll get is to enforce a naming rule on your packages. For example:
MYSCHEMA.PKG_PEOPLE
MYSCHEMA.PKG_PEOPLE_CRUD
I have read these very good questions on SO about SQL stored procedures:
When should you use stored procedures? and
Are Stored Procedures more efficient, in general, than inline statements on modern RDBMS’s?
I am a beginner on integrating .NET/SQL though I have used basic SQL functionality for more than a decade in other environments. It's time to advance with regards to organization and deployment. I am using .NET C# 3.5, Visual Studio 2008 and SQL Server 2008; though this question can be regarded as language- and database- agnostic, meaning that it could easily apply to other environments that use stored procedures and a relational database.
Given that I have an application with inline SQL queries, and I am interested in converting to stored procedures for organizational and performance purposes, what are your recommendations for doing so?
Here are some additional questions in my mind related to this subject that may help shape the answers:
Should I create the stored procedures in SQL using SQL Management Studio and simply re-create the database when it is installed for a client?
Am I better off creating all of the stored procedures in my application, inside of a database initialization method?
It seems logical to assume that creating stored procedures must follow the creation of tables in a new installation. My database initialization method creates new tables and inserts some default data. My plan is to create stored procedures following that step, but I am beginning to think there might be a better way to set up a database from scratch (such as in the installer of the program). Thoughts on this are appreciated.
I have a variety of queries throughout the application. Some queries are incredibly simple (SELECT id FROM table) and others are extremely long and complex, performing several joins and accepting approximately 80 parameters. Should I replace all queries with stored procedures, or only those that might benefit from doing so?
Finally, as this topic obviously requires some research and education, can you recommend an article, book, or tutorial that covers the nuances of using stored procedures instead of direct statements?
Consider skipping stored procedures for an ORM. Consider using:
LINQ To SQL
Entity Framework
SubSonic
You'll be writing less boiler plate ListCustomer and GetCustomerByID code when you could be adding more value to your application.
IMO, there isn't any real compelling reason to choose stored procedures with the modern toolset that we have in the Microsoft stack.
The move away from inline SQL statements is good, and an ORM will help parameterize your queries for you. You don't have to think about it.
You don't have to mess with ADO.NET objects at all. Code your data access in an object oriented fashion.
There are several compelling reasons to avoid giving table access to very many logins, including application logins, and these drive the use of stored procedures. (I generally do not ascribe any importance to using SPs for performance reasons - SQL Server caches even adhoc query plans).
Stored procedures give your database much more capability in defining its interface boundaries. In many cases, views are not sufficient to control the interface.
Any framework built solely on tables and views (note that many frameworks can build on top of SP results) is going to be severely limited in letting your database protect itself and control itself.
As a simple example, neither tables nor views can be parameterized. If you have a very large table or view and you want to enforce all users to specify a certain set of filter criteria (for instance a snapshot date or effective date), there is no way to enforce this at the database call interface. The framework can submit queries for all time. If the table/view is not exposed, and the only interface is through an SP or table-valued UDF, then the parameters to that SP or UDF MUST be provided, thus satisfying your database's need to ensure that it is used properly.
Other examples, where views may or may not work, include hiding privacy information for certain users, hiding internal keys, hiding internal implementation details, and enforcing complex security rules.
As far as scripting the creation of your database schema, including objects in the correct dependency order, there are several tools to do this (and generate change scripts), including Red Gate SQL Compare and Apex SQLScript.
Use stored procedures if you really have a performance requeriment, particularly if one stored procedures will be called thousands of times per minute. This way sql engine avoids severals steps for processing the statement. GPS Tracking systems is an example. Say you have 10000 vehicles which reports a 3 positions per minute. In this case stored procedures helps performance.
If not, instead of CRUD sql statements, use ORM features.
You missed one:
When is it better to write "ad hoc sql" vs stored procedures
My answer is: don't use stored procedures at all.