Progress DB Engine Is Stupid About Some Things

BCM

Member
I have occassional need to build routines that copy data from our Progress database to SQL Server. A simple way to quickly generate an empty table structure is to issue a SELECT ... INTO <TABLENAME> FROM ... WHERE <your criteria> AND 1 <> 1. Because the number 1 is always equal to 1 no records will be returned, but the table structure will be created. With a robust database engine the above query completes in a fraction of a second because the database engine determines that no records will pass the test where 1 <> 1. However, Progress just blindly proceeds to scan all rows.

To be fair, I used the Procedure Editor to try a similar test in 4GL. Go ahead, you try: "FOR EACH <TABLE> WHERE 1 <> 1 NO-LOCK: END."
Sure enough, Progress scanned every row. Frankly, my dog is smarter than this.
 

Casper

ProgressTalk.com Moderator
Staff member
Hi BCM,

Did you ever try to order "One cop of coffee" in France without speaking french? If you don;t get it then you proabably blame the french for that.
But go ahead, sure you know what you say, the problem is you're speaking the wrong language....

No matter how many times you keep repeatng youreself Progress isn't going to change because of you.
You sound like an old record which keeps repeating the same track. Don't you really have something else to do, but hanging out here complaining how miserable your life is with Progress. I really don't understand what you're hanging out here for. If I was so disguisted like you with Progress then I wouldn't even bother to come here and make a fool of myself every time. Or maybe Oracle is so superior your job became obsolete and this is the only place in the world where peolpe give you at least some attention.....

I feel sorry for you.

Regards,

Casper.
 

Casper

ProgressTalk.com Moderator
Staff member
Oh you mean I got a point there?

Great vocabulary! :D

Regards,

Casper
 
BCM said:
"FOR EACH <TABLE> WHERE 1 <> 1 NO-LOCK: END."
Sure enough, Progress scanned every row. Frankly, my dog is smarter than this.

Due to a known Progress limitation, the 4GL engine presumes the programmer has at least one brain cell.
 

BCM

Member
I am sincerely interested in the answer to these two questions:

(1) What type of system or application problem does Progress 4GL enable solving significantly better than other languages?

(2) What type of system or application problem does the Progress database handle significantly better than set-based databases (example: db2, Oracle, SQL Server, MySQL, etc.)?

I really am interested to know this because so far I haven't found it. Perhaps, that is because I usually work with business applications which need to provide robust data analysis and statistics across sets of records. At other times I have worked with pure communication processing having no database or visual front-end and best handled by pure C code on an operating system other than Windows.

Please help me to understand the inherent strengths of Progress and the wisdom of using it. Just so you know, I discount "ease of development" as a reason because that may be the programmer's choice without regard to the nature of the problems being solved. My opinion is that the best tools are the ones that result in the best system not the tools that may be the easiest for me to use. That is why I have developed in assembler, C, C++, C#, Basic, Visual Basic, Delphi (object-oriented Pascal), SAS, Mark IV, DMS/ISPF, Clipper, Focus, and Progress 4GL using databases db2, Focus, Oracle, SQL Server, dBase, Progress, IMS. I have been fortunate enough to avoid developing in MS Access.

So, please give me your answer to the two questions, above, and help me to understand what Progress is good at.
 
BCM said:
I discount "ease of development" as a reason because that may be the programmer's choice without regard to the nature of the problems being solved.

Notice how BCM cleverly rules out the major reason that many of us use Progress.

Kind of like me saying: "BCM: what's the best reason for using Oracle? Oh, by the way, don't include its database facilities."
 

BCM

Member
Lee,
Are you saying that the reason to choose Progress is simply ease of development? What if the application that is developed does not integrate well with the customer's other systems? What if the customer is limited in the tools available to use with the application after it is delivered? I'm trying to understand the true motivation for choosing Progress.

I believe that programmers, also, choose MS Access for ease of development. However, that does not make Access a good choice from the perspective of the customer.
 

Casper

ProgressTalk.com Moderator
Staff member
Blabla,

Like I said, same old, same old. Obviously you're not convinced that Progress is going to mean something to you. Well, good for you!
If you read my posts regarding Oracle and progress and you still don't get the point then what's more to say...
So you do with your superiority what you want to do and humble me am doing my thing. So why bother to get excited?
Be happy with Oracle and stay away from stuff you obviously can't comprehend.
But he lets be forgiving:
Yep Oracle has better online functionality and yes Oracle has a very good SQL optimiser. (to name some)
But that's not the point, neither is the point what database is best. Every problem has it's own best solution. The problem with you is that you're obviously so blinded with this hate for Progress that I start to believe you're either unemployed or you need medication. How is to be an misunderstood (unknown) Oracle Evangelist?

I'm much more interseted in real problems. Not so much in some personal vendatta.

Hey, I got an idea, go to the microsoft forums and tell them how stupid they are to use an unstable, unsafe OS based om some lousy chip design compared to the superiour UNIX systems and RISC processors? Or are you hanging there as well talking to people about the light you've seen?

Casper.
 

BCM

Member
Casper, here's why I get excited, because I am extremely glad that Boeing and McDonnell Douglas do not manufacture aircraft out of materials that are simply the easiest for them to work with. To me, the creator(s) of Progress have wrought a very seriously, defective tool on the world and convinced inexperienced programmers to use it, resulting in their addiction to Progress and the introduction into our systems environment of applications that cause nightmares at the customers' sites. Therefore, it is my fervent desire that the creator(s) of Progress publicly admit their profound error and commit suicide out of shame.
 

Casper

ProgressTalk.com Moderator
Staff member
You'd be surprised to see that there are company's that use Progress deliver goods to them on time :biggrin:

Hmm, I like your energy though, maybe you should put this energy in something really important like self reflection.
I've seen many very very bad Oracle applications even though they had acces to, in your words, the most superior database design in the universe. How is that possible, you ask?
Well maybe it's not only the tools that make a good product, but maybe it has to do with some other craftsmanship as well.

An what is wrong with ease of development?
I got no problem with Progress and integration. You obviously have, maybe take some training, upgrade your Progress version, RTFM?

Casper.

And by the way, now you're on your quest: how do you feel of airplains using MicroSoft technology? Maybe Bill Gates and Progress can come to your house and appologize for not consulting you first after starting a very good bussiness?
 
BCM,

This is why I like Progress:


[Visual Basic]

Code:
 // Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

private const String TABLENAME                = "TBL0711";
private const String TABLENAME_COMBOBOXSOURCE = "TBL0709_ComboBoxSource";
private const String RELATIONNAME             = "REL0711";

private DataSet ds;
private SqlDataAdapter da;

private BindingManagerBase bm;

//  . . . 

private void ComboBoxForm_Load(object sender, System.EventArgs e)
{
    // Create the DataSet.
    ds = new DataSet( );

    // Create the select and update commands for the DataAdapter.
    String selectCommand = "SELECT Id, ComboBoxItemId, Field1 FROM " +
        TABLENAME;
    String updateCommand = "UPDATE " + TABLENAME + " " +
        "SET ComboBoxItemId = @ComboBoxItemId, Field1 = @Field1 " +
        "WHERE Id = @Id";

    // Create the DataAdapter.
    da = new SqlDataAdapter(selectCommand,
        ConfigurationSettings.AppSettings["Sql_ConnectString"]);
    da.UpdateCommand = new SqlCommand(updateCommand,
        da.SelectCommand.Connection);
    da.UpdateCommand.CommandType = CommandType.Text;
    da.UpdateCommand.Parameters.Add("@Id", SqlDbType.Int, 0, "Id");
    da.UpdateCommand.Parameters.Add("@ComboBoxItemId", SqlDbType.Int, 0,
        "ComboBoxItemId");
    da.UpdateCommand.Parameters.Add("@Field1", SqlDbType.NVarChar, 50,
        "Field1");
    
    // Retrieve the data and schema for the table.
    da.FillSchema(ds, SchemaType.Source, TABLENAME);
    da.Fill(ds, TABLENAME);

    // Create and fill the schema for the ComboBox table.
    String sqlText = "SELECT ComboBoxItemId, Description FROM " +
        TABLENAME_COMBOBOXSOURCE;
    SqlDataAdapter daCB = new SqlDataAdapter(sqlText,
        da.SelectCommand.Connection);
    DataTable comboBoxSourceTable =
        new DataTable(TABLENAME_COMBOBOXSOURCE);
    daCB.FillSchema(comboBoxSourceTable, SchemaType.Source);
    // Sdd the instructions for the user as the first element.
    comboBoxSourceTable.Rows.Add(new object[] {-1, "<Select>"});
    // Fill the rest of the data for the ComboBox.
    daCB.Fill(comboBoxSourceTable);

    // Add the ComboBox source table to the DataSet.
    ds.Tables.Add(comboBoxSourceTable);

    // Relate the parent and ComboBox tables.
    ds.Relations.Add(new DataRelation(RELATIONNAME,
        ds.Tables[TABLENAME_COMBOBOXSOURCE].Columns["ComboBoxItemId"],
        ds.Tables[TABLENAME].Columns["ComboBoxItemId"],
        true));

    // Set up the ComboBox with the DataSet.
    comboBox.DataSource = ds.Tables[TABLENAME_COMBOBOXSOURCE];
    comboBox.ValueMember = "ComboBoxItemId";
    comboBox.DisplayMember = "Description";

    // Bind all of the controls to the DataSet.
    idTextBox.DataBindings.Add("Text", ds, TABLENAME + ".Id");
    comboBox.DataBindings.Add("SelectedValue", ds,
        TABLENAME + ".ComboBoxItemId");
    field1TextBox.DataBindings.Add("Text", ds, TABLENAME +  ".Field1");

    // Get the binding manager base for the parent table.
    bm = BindingContext[ds, TABLENAME];
}
======================




[Progress]

Drop combo-box on form, then:

Code:
   FOR EACH table NO-LOCK:

      cbTable:ADD-LAST(table.field).

  END.

===================================


[Oracle]


God knows. Something horrible.


HTH

Lee
 

rhi

Member
Lee Curzon said:
BCM,

This is why I like Progress:


[Visual Basic]

Code:
 // Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
 
private const String TABLENAME                = "TBL0711";
private const String TABLENAME_COMBOBOXSOURCE = "TBL0709_ComboBoxSource";
private const String RELATIONNAME             = "REL0711";
 
private DataSet ds;
private SqlDataAdapter da;
 
private BindingManagerBase bm;
 
//  . . . 
 
private void ComboBoxForm_Load(object sender, System.EventArgs e)
{
    // Create the DataSet.
    ds = new DataSet( );
 
    // Create the select and update commands for the DataAdapter.
    String selectCommand = "SELECT Id, ComboBoxItemId, Field1 FROM " +
        TABLENAME;
    String updateCommand = "UPDATE " + TABLENAME + " " +
        "SET ComboBoxItemId = @ComboBoxItemId, Field1 = @Field1 " +
        "WHERE Id = @Id";
 
    // Create the DataAdapter.
    da = new SqlDataAdapter(selectCommand,
        ConfigurationSettings.AppSettings["Sql_ConnectString"]);
    da.UpdateCommand = new SqlCommand(updateCommand,
        da.SelectCommand.Connection);
    da.UpdateCommand.CommandType = CommandType.Text;
    da.UpdateCommand.Parameters.Add("@Id", SqlDbType.Int, 0, "Id");
    da.UpdateCommand.Parameters.Add("@ComboBoxItemId", SqlDbType.Int, 0,
        "ComboBoxItemId");
    da.UpdateCommand.Parameters.Add("@Field1", SqlDbType.NVarChar, 50,
        "Field1");
 
    // Retrieve the data and schema for the table.
    da.FillSchema(ds, SchemaType.Source, TABLENAME);
    da.Fill(ds, TABLENAME);
 
    // Create and fill the schema for the ComboBox table.
    String sqlText = "SELECT ComboBoxItemId, Description FROM " +
        TABLENAME_COMBOBOXSOURCE;
    SqlDataAdapter daCB = new SqlDataAdapter(sqlText,
        da.SelectCommand.Connection);
    DataTable comboBoxSourceTable =
        new DataTable(TABLENAME_COMBOBOXSOURCE);
    daCB.FillSchema(comboBoxSourceTable, SchemaType.Source);
    // Sdd the instructions for the user as the first element.
    comboBoxSourceTable.Rows.Add(new object[] {-1, "<Select>"});
    // Fill the rest of the data for the ComboBox.
    daCB.Fill(comboBoxSourceTable);
 
    // Add the ComboBox source table to the DataSet.
    ds.Tables.Add(comboBoxSourceTable);
 
    // Relate the parent and ComboBox tables.
    ds.Relations.Add(new DataRelation(RELATIONNAME,
        ds.Tables[TABLENAME_COMBOBOXSOURCE].Columns["ComboBoxItemId"],
        ds.Tables[TABLENAME].Columns["ComboBoxItemId"],
        true));
 
    // Set up the ComboBox with the DataSet.
    comboBox.DataSource = ds.Tables[TABLENAME_COMBOBOXSOURCE];
    comboBox.ValueMember = "ComboBoxItemId";
    comboBox.DisplayMember = "Description";
 
    // Bind all of the controls to the DataSet.
    idTextBox.DataBindings.Add("Text", ds, TABLENAME + ".Id");
    comboBox.DataBindings.Add("SelectedValue", ds,
        TABLENAME + ".ComboBoxItemId");
    field1TextBox.DataBindings.Add("Text", ds, TABLENAME +  ".Field1");
 
    // Get the binding manager base for the parent table.
    bm = BindingContext[ds, TABLENAME];
}
======================




[Progress]

Drop combo-box on form, then:

Code:
   FOR EACH table NO-LOCK:
 
      cbTable:ADD-LAST(table.field).
 
  END.

===================================


[Oracle]


God knows. Something horrible.


HTH

Lee

It depends on how you do it, since you have literally 1000's of choices in development software for Oracle databases, but one nice one from Oracle is called Application Express Studio. You can create & deploy a web based application, and not even have to write a single line of code.
Check it out:
http://apex.oracle.com/studio
 

rhi

Member
If you want to try it, go to this link and click "Request A Workspace" and fill ou the registration. when you receive your login info, you can log in and begin creating an app. I created a form and a report in less than 1 minute - with zero code.

http://htmldb.oracle.com/pls/otn
 

joey.jeremiah

ProgressTalk Moderator
Staff member
oh, my god you've discovered wysiwyg.

you're starting to sound like the mpowell version for oracle.
 

rhi

Member
well, I guess you could refer to it as WYSIWYG, but I think it is quite a bit more, since this is more than web page/content creation. It is a full blown transactional application development tool intended for enterprise level use.
(Hmmm .. . . . wonder how much longer developers will be needed if your average user can do this themselves?):awink:
 

joey.jeremiah

ProgressTalk Moderator
Staff member
development tools for reports, user interface, schema etc. are a huge help for
productivity.

but you can't do everything with them no matter how much features and
option you cram into them.

languages aren't going to go away anytime soon.

besides i doubt users should know about entities, relationships, transactions,
indices etc. they've got other jobs to do.
 

BCM

Member
This post is not a complaint or criticism. The example you offered, Joey, is in the context of screens and visual input/output. I sometimes create screens, forms, windows (whatever you would like to call them). However, much of my work deals with processing and/or analyzing raw data in bulk. From my own experience I know that Progress 4GL is quite capable of performing the kind of processing to which I am referring. And, I, also, know that Progress 4GL has no way to handle matrices of processing. The downside of this is the sheer elapsed time required to perform this kind of processing with Progress 4GL.

I'd like to use a scavenger hunt as an example because, to me, that's how Progress forces us to proceed through the processing.

Set next house = 1.

(1) Find the next house.
(2) Find the closest neighbor who has a greater address than the original house in (1).
(3) Find the house of the first born from the house in (2).
(4) Obtain the annual income of the head of household in (3).
(5) Increment the next house and return to (1) above.

This works well. The processing time is insignificant for small sets of houses, neighbors, and first born. However, the processing time becomes significantly large when the record count grows to 1,000,000+.

In SQL the processing may be performed in a single SQL statement that executes in seconds or a couple minutes even when the record count exceeds 1,000,000. The reason is all in the database engine.

Imagine a financial institution that has millions of accounts. With Progress the nightly processing would take more hours than are available. This is precisely the problem my firm is facing. The nightly processing is eating up a 12-hour window. Because we have business locations in three different U.S. timezones, we have run out of processing hours. Currently, I am developing alternate processing on SQL Server for a process that is currently taking 2-3 hours each night. On SQL Server the same process takes less than 2 minutes. I'd like to add that our Progress 9.1D database is running on a more powerful server than our SQL Server database.
 
Top