I have to fetch data from DB2 database from a .NET in following way:
join 5 tables 2 inner join 3 left outer join
the data have to be written on a text file . so functions such as LPAD/RPAD, substr etc for formatting have to be used.
the data retrieved would be about 100000 rows
I am planning to create a view so that application gets rid of joins and i get required columns only in the view.
I want to know If formatting of data should also be moved to the definition of view? So that in the application I will perform only
select * from view
Please advice
Thanks
There is really no difference from the database engine's perspective whether the application submits a query with joins, text functions, etc or if all of these are contained within a view and the application executes a simple select * from view. DB2 compiles the query in exactly the same way.
The only "advantage" to using a view is convenience for the application developer. The disadvantage to putting the SQL statement into a view, of course, is that if the requirements change you'll have to modify the view.
As far as including the text formatting within the view: If this view will exist ONLY to support this one single application (and you're using it only for convenience), then it may make sense to include the formatting within the view definition. However, if other applications may have some need for the view (but not the text formatting), then keeping the formatting in your query against the view is the better choice.
As a DBA, I would suggest that the best place for text formatting is within your application code. Writing a formatted string using printf() (or equivalent) is something that applications are usually pretty good at.
Related
I'm working on a portal based on Orchard CMS. We're using Orchard to manage the "normal" content of the site, as well as to model what's essentially data for a small application embedded in it.
We figured that doing it that way is "recommended" for working in Orchard, and that it would save us duplicating a bunch of effort in features that Orchard already provides, mainly generating a good enough admin UI. This is also why we're using fields wherever possible.
However, for said application, the client wants to be able to display the data in the regular UI in a garden-variety datagrid that can be filtered, sorted, and paged.
I first tried to implement this by cobbling together a page with a bunch of form elements for the filtering, above a projection with filters bound to query string parameters. However, I ran into the following issues with this approach:
Filters for numeric fields crash when the value is missing - as would be pretty common to indicate that the given field shouldn't be considered when filtering. (This I could achieve by changing the implementation in the Orchard source, which would however make upgrading trickier later. I'd prefer to keep anything I haven't written untouched.)
It seems the sort order can only be defined in the administration UI, it doesn't seem to support tokens to allow for the field to sort by to be changed when querying.
So I decided to dump that approach and switched to trying to do this with just MVC controllers that access data using IContentQuery. However, there I found out that:
I have no clue how, if at all, it's possible to sort the query based on field values.
Or, for that matter, how / if I can filter.
I did take a look at the code of Orchard.Projections, however, how it handles sorting is pretty inscrutable to me, and there doesn't seem to be a straightforward way to change the sort order for just one query either.
So, is there any way to achieve what I need here with the rest of the setup (which isn't little) unchanged, or am I in a trap here, and I'll have to move every single property I wish to use for sorting / filtering into a content part and code the admin UI myself? (Or do something ludicrous, like create one query for every sortable property and direction.)
EDIT: Another thought I had was having my custom content part duplicate the fields that are displayed in the datagrids into Hibernate-backed properties accessible to query code, and whenever the content item is updated, copy values from these fields into the properties before saving. However, again, I'm not sure if this is feasible, and how I would be able to modify a content item just before it's saved on update.
Right so I have actually done a similar thing here to you. I ended up going down both approaches, creating some custom filters for projections so I could manage filters on the frontend. It turned out pretty cool but in the end projections lacked the raw querying power I needed (I needed to filter and sort based on joins to aggregated tables which I think I decided I didn't know how I could do that in projections, or if its nature of query building would allow it). I then decided to move all my data into a record so I could query and filter it. This felt like the right way to go about it, since if I was building a UI to filter records it made sense those records should be defined in code. However, I was sorting on users where each site had different registration data associated to users and (I think the following is a terrible affliction many Orchard devs suffer from) I wanted to build a reusable, modular system so I wouldn't have to change anything, ever!
Didn't really work out quite like I hoped, but to eventually answer the question in your title: yes, you can query fields. Orchard projections builds an index that it uses for querying fields. You can access these in HQL, get the ids of the content items, then call getmany to get them all. I did this several years ago, and I cant remember much but I do remember having a distinctly unenjoyable time with it haha. So after you have an nhibernate session you can write your hql
select distinct civr.Id
from Orchard.ContentManagement.Records.ContentItemVersionRecord civr
join civ.ContentItemRecord cir
join ci.FieldIndexPartRecord fipr
join fipr.StringFieldIndexRecord sfir
This just shows you how to join to the field indexes. There are a few, for each different data type. This is the string one I'm joining here. They are all basically the same, with a PropertyName and value field. Hql allows you to add conditions to your join so we can use that to join with the relevant field index records. If you have a part called Group attached directly to your content type then it would be like this:
join fipr.StringFieldIndexRecord sfir
with sfir.PropertyName = 'MyContentType.Group.'
where sfir.Value = 'HR'
If your field is attached to a part, replace MyContentType with the name of your part. Hql is pretty awesome, can learn more here: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html But I dunno, it gave me a headache haha. At least HQL has documentation though, unlike Orchard's query layer. Also can always fall back to pure SQL when HQL wont do what you want, there is an option to write SQL queries from the NHibernate session.
Your other option is to index your content types with lucene (easy if you are using fields) then filter and search by that. I quite liked using that, although sometimes indexes are corrupted, or need to be rebuilt etc. So I've found it dangerous to rely on it for something that populates pages regularly.
And pretty much whatever you do, one query to filter and sort, then another query to getmany on the contentmanager to get the content items is what you should accept is the way to go. Good luck!
You can use indexing and the Orchard Search API for this. Sebastien demoed something similar to what you're trying to achieve at Orchard Harvest recently: https://www.youtube.com/watch?v=7v5qSR4g7E0
If making things work is only requirement, we can put all controlling login and DB handling logic even in the views & it will work. However this is not a right approach for reusable design.
Before I ask my real design question, below is my current understanding about separation of responsibilities in terms of model.
All Database related code, even db related logic, should go in models.
For a table, say 'my_tab', propel generate 4 classes, out of which only 2 classes 'MyTab.php' and 'MyTabPeer.php' should be edited.
MyTabPeer.php must only have data fetching.
Any logic, if required to fetch data, should go in 'MyTab.php'
This is simple and I hope it is correct, if not, please correct me.
Now, I have a special condition. I've 4 tables, say a, b, c, d. For that, propel generated 8 editable classes (excluding base*.php)
A.php APeer.php B.php BPeer.php
C.php CPeer.php D.php DPeer.php
One page of my application, shows Mailbox (say). Mailbox is not a table in database but it gets its data from complex join query between above 4 tables along with lot of calculation/conditions.
I generated that query, fetch data from it and displayed it. Mailbox is running as expected. However I did it in my controller (action class), which I know is not a right place for that.
My question is, where should I put that code? Possible options:
Controller, I think, is not a right place for DB logic/fetch.
I've 8 model classed however data do not belong to any one of them but as combination of them all.
A separate helper/lib, but I know I'll never reuse that code as its unique page of the site.
Anywhere else?
Please suggest if I'm wrong but I guess I should put it in models as it is fetching data. Since A is primary table, I probably should put code in A.php and APeer.php. If that is correct place, next question is, What should go in A.php & what should go in APeer.php? I've following operations to do:
Some logic to decide what columns, should I select.
As like mailbox, I can show received/sent message. Controller will tell what to show but there are some db logic to set conditions.
Then really fetch data from complex Join query.
Returned data will have all rows but I might need to merge few rows conditionally.
As per my understanding, Point 3 should go in APeer.php and rest in A.php. Is my understanding correct?
You should create separate model class i.e. Mailbox.
Method of this model should do the complex select and return data to your action in controller. This solution will not break MVC approach.
I have a working system that lets me build a database containing instances of various entities , all linked together nicely.
Before I knew I would care, I came across a tutorial on using Core Data and bindings, and it went through a complete case where you get a table showing all the entities of some type with a column for each property. It showed both the UI side and the Data model side - not that I need the data model part at this point. Now, darned if I can find it. This is one of those things that is supposed to be easy, and requires virtually no code, but getting exactly the right connections in UIBuilder is not going to happen if I can't find instructions.
Also, I thought I came across an example of something like a query editor where the user could select which properties to sort on, which to match on, etc. Did I imagine that?
Anyone out there know where I can find such?
Sure, you can do this without code:
Add an array controller to your nib.
Bind or connect an outlet for its managed object context
Set the array controller to Entity mode, fill in the entity name, and select Prepares Content.
Bind your table view columns to array controller's arranged objects, and fill in the key name for the model key.
Regarding the query editor, open up the model, and on the Editor menu click Add Fetch Request.
I found at least a partial answer to the query editor question, in this apple tutorial. Not sure how far it will get me, as I prefer to write code where possible, since then I can leave a trail of comments.
I'm currently running in a multi-DB SQL Server environment and using linq to sql to perform queries.
I'm using the approach documented here to achieve cross DB joins:
http://www.enderminh.com/blog/archive/2009/04/25/2654.aspx
so basically:
2 data contexts - Users and Payments
Users.dbo.UserDetails {PK: UserId }
Payments.dbo.CurrentPaymentMethod { PK: UserId }
I drag the tables onto the DBML, and in the properties window, change the Source from dbo.UserDetails to Users.dbo.UserDetails to fully qualify the DB name.
I can then issue a single data context cross DB join by doing something like:
var results = (from user in datacontext.Table<UserDetail>()
join paymentmethod in dataContext.Table<CurrentPaymentMethod>() on user.UserId equals paymentmethod.UserId
... rest of query here ...);
Now this is tickety boo and works as I want it to. The only problem I'm currently having is when schema updates etc. happen (which is relatively frequent as we're in a significant dev phase).
(and finally, the question!)
What I want to achieve (and I've marked the question up as T4 as a guess, as I know that the DBML files are T4 guided) is an automated way when I drag any table onto a data context that the Source automatically picks up the DB name (so will have Users.dbo.UserDetails instead of just dbo.UserDetails)?
Thanks for any pointers :)
Terry
Have a look at the T4 Toolbox and the LinqToSql code generator it provides (Courtesy of Oleg Sych) - You can customize the templates to generate references however you'd like, but I think the problem you're going to run into is that the database name isn't stored in the dbml file.
What you could probably do is add a filter to the generator, perhaps using a dictionary or similar, such that in your .tt file, you maintain a list of tables and the databases they belong to. That way, if your maintenance task is to delete the class from the designer and drop it on again, it will get the right database name.
I am in the process building myself a simple Linq to SQL repository pattern.
What I wanted to know is, is it possible to set a default sort column so I don't have to call orderby.
From what I have read I don't think it is and if this is the case what would recommend for a solution to this problem.
Would the best idea be to use an attribute on a partial class on my model?
the default order is the clustered index on the table you are pulling from.
What are you wanting to sort on (without sorting on) ?
If you needed something other than having it sorted by the primary key, you could look at supplying a select statement for the table instead of using the runtime generated statement. Look at the properties on the table in the designer -- you should be able to override the runtime generated select, delete, and update statements. I don't personally recommend this, though, since I'm not sure how it will interact with other orderings. I think the intent is more along the lines of allowing you to use stored procedures if you want.
Another alternative would be to create a table-valued function or stored procedure that does the ordering the way you want and has the same schema as the table. If, in the designer, you drag this onto the table, you get a strongly typed method on the data context that you can use to obtain those entities according to the definition of the function/procedure instead of the standard select. Personally I think this introduces fewer maintenance headaches because it makes it more visible, but you do have to remember to use the method instead of the Table property for that entity.