• (cs)

    Is this what people mean when they preach against using "dynamic sql" ? [:O]

  • Mig-O (unregistered)

    <cite>...we learned how vital enterprise application are for proactive organizations leveraging collective synergy to think outside the box and formulate their key objectives into a win-win game plan with a quality-driven approach that focuses on empowering key players to drive-up their core competencies and increase expectations with an all-around initiative to drive up the bottom-line.</cite>

    LOL
    buzzword bashing at its best

    PS: First?

  • Seltsam (unregistered)

    Yes!  My company's product has a huge list of constants.  Some of which are just as silly as those above.

  • darthCodex (unregistered)

    The real WTF is ofcourse that they use SELECT STAR instead of specifying the columns they really need.

  • Colin (unregistered)

    SqlMisc.NUMBERS_ONE;


    OH THANK GOD! Just in case the number one changes to 'blue' or something.


    "GIMME # sourced table conditioned action%blue"

  • Ricky (unregistered) in reply to darthCodex

    Thats not really bad.
    In fact, if you do a test -- you will see that using select * is on average faster that specifying all the columns!
    -Ricky

  • Ragnaros (unregistered) in reply to Ricky

    IDIOTS!!!

  • beefcake (unregistered)

    OH MY GOD 

  • (cs)

    This WTF gets (4 * SqlWords.STAR) out of 5 for WTFness.

  • Code Slave (unregistered)

    Let's take this to n'th degree

    public class SqlWords
    {
      public const string SPACE _CHAR= " ";

    //...
      public const string E_CHAR = "E";

    //...
      public const string L_CHAR = "L";

    //....
      public const string S_CHAR = "S";
    }

    public class SqlWords
    {
      public const string SELECT = SPACE_CHAR + S_CHAR + E_CHAR + //...

    <FONT color=#000000>}</FONT>

    <FONT color=#000000>Perhaps that's n-2'th, but there's no way I'm going to hex of binary.</FONT>

  • anonymous (unregistered)
    Alex Papadimoulis:

    If you're looking at today's code and thinking, gee, shouldn't these be in stored procedures, or views, or something...



    For some reason or another, I've worked with many DBA's in the past that absolutely forbid the use of stored procedures, views, triggers, etc (basically anything besides tables and indexes).  Basically, the argument is that once you start doing that, you're starting to embed application logic in the database.

    I don't know if I'm for or against this kind of practice.... Has anybody dealt with DBA's who take this stance?

    CAPTCHA: SOLDIER, I mean
    CAPTCHA: salad
  • (cs) in reply to darthCodex

    <font size="2">return Words.WHAT + Words.THE + Words.EXPLETIVE_OF_CHOICE + Punctuation.QUESTION_MARK;

    </font>

  • (cs)
    Alex Papadimoulis:
      public const string INNER = " INNER ";
      public const string JOIN = " JOIN ";
      public const string INNER_JOIN = " INNER JOIN ";
       


    Allright.  Following this, we may have:
    public const string SELECT_STAR_FROM = " SELECT * FROM ";

    And so on...

     
  • Destroyer (unregistered) in reply to Romeo
    Romeo:
    Alex Papadimoulis:
      public const string INNER = " INNER ";
      public const string JOIN = " JOIN ";
      public const string INNER_JOIN = " INNER JOIN ";
       


    Allright.  Following this, we may have:
    public const string SELECT_STAR_FROM = " SELECT * FROM ";

    And so on...


     

    How about:

    public const string SELECT_STAR_FROM = SELECT + " " + STAR + " " + FROM;

  • (cs)

    <FONT face="Courier New">public class Hello
     {
        public const string HELLO "Hello";
     }</FONT>

    <FONT face="Courier New">public class Space
     {
        public const string SPACE " ";
     }</FONT>

    <FONT face="Courier New">public class World
      {
        public const string WORLD "World";</FONT>

    <FONT face="Courier New">public class ExclamationPoint
     {
        public const string EXCLAIM "!";
     }</FONT>

    <FONT face="Courier New">public class Output
     {
        public const string OUTPUT = Hello.HELLO + Space.SPACE + World.WORLD + ExclamationPoint.EXCLAIM;
     }</FONT>

    I'm going to reapply for that job at my local university, now that I'm all enterprisey.

  • (cs) in reply to Code Slave

    Anonymous:
    <FONT color=#000000>Perhaps that's n-2'th, but there's no way I'm going to hex of binary.</FONT>

    N minus tooth?

  • Ragnaros (unregistered) in reply to Ragnaros

    I take it back. I understand why they did this. It's because the SQL needs to be globalized. If it's going to run in Mexico, for example,

    <FONT face="Courier New" color=#000000>"TENER Productos.*, Empleados.* DE Productos, Empleados DONDE ProductoID ES " + Constants.TWENTY_TWO + " Y NUMERO_INTENTOS ES MENOR QUE @PrimerConta JUNTOS CON Departmento EN EmpleadoID"</FONT>

    <FONT face="Times New Roman" color=#000000>

    It's been a while since I have written SQL in Spanish, but I'm pretty sure this is right. These guys built exactly what I need.

    Except now my spanish SQL statement has nasty English words in it like "Constants" and "TWENTY_TWO"

    </FONT>
  • daBowmore (unregistered)

    Gotta love that SqlWords.STAR! I will definitely use that everywhere in my enter- or returnprise piece of applications!

  • Ash (unregistered)

    Well... at least they can use code completion now...

  • (cs)
    Alex Papadimoulis:

    If you're looking at today's code and thinking, gee, shouldn't these be in stored procedures, or views, or something, then you're still thinking in the world of unenterpriseness

      
      /* SNIP */
    

    public class SqlQueries { public const string SELECT_ACTIVE_PRODCUTS = SqlWords.SELECT + SqlWords.STAR + SqlWords.FROM + SqlTables.PRODUCTS + SqlWords.WHERE + SqlColumns.PRODUCTS_ISACTIVE + SqlWords.EQUALS + SqlMisc.NUMBERS_ONE;

    /* SNIP */

    public const string UPDATE_LOGON = SqlWords.UPDATE + SqlTables.CREDENTIALS + SqlWords.SET + SqlColumns.CREDENTIALS_LOGON_NAME + SqlWords.EQUALS + SqlMisc.PARAMS_FIRST + SqlWords.COMMA + SqlColumns.CREDENTIALS_LOGON_PASS + SqlWords.EQUALS + SqlMisc.PARAMS_SECOND; }

      Looking at the second SQL string, I can't quite figure out where you would need a constant update statement. Other than some kind of "lets reset something or another", where would such a statement be useful? I'm thinking that perhaps this is part of some kind of setup program and it is used to initially condition the database for usage. Since the update statement contains a reference to "PARAMS_FIRST" and "PARAMS_SECOND", it may be used to actually generate a stored procedure (e.g."create procedure <something or another> <some input params> as " + UPDATE_LOGON).

  • (cs)
    Alex Papadimoulis:

    ... I should note that this approach also pads your code against changes in the SQL language. I've heard from some good sources that the next version of SQL will use the word "GIMMIE" instead of "SELECT".

    too bad they used const instead of static readonly, they will have to recompile all the applications that are using those assemblies if SQL makes a change to the key words!!

  • (cs) in reply to anonymous
    Anonymous:
    Alex Papadimoulis:

    If you're looking at today's code and thinking, gee, shouldn't these be in stored procedures, or views, or something...



    For some reason or another, I've worked with many DBA's in the past that absolutely forbid the use of stored procedures, views, triggers, etc (basically anything besides tables and indexes).  Basically, the argument is that once you start doing that, you're starting to embed application logic in the database.

    I don't know if I'm for or against this kind of practice.... Has anybody dealt with DBA's who take this stance?


    While today's post is a great WTF, if what you are saying about those DBAs is true, then they have taken the top "WTF" prize for the day.  That might be one of the stupidest things I have ever heard.  Did you really work with *many* of them? That's a scary thought.
  • Corentin (unregistered)

    A great design indeed, if you want to write your SQL requests in klingon language.

    Truly an Enterprise system! (despite the lack of XML)

  • (cs)

    The best part of this is that the compiler is more likely than not inlining all of their constants into

    public const string SELECT_ACTIVE_PRODUCTS = SELECT * FROM PRODUCTS WHERE PRODUCTS_IS ACTIVE = 1

  • (cs)

    What's most important here, is that the developer is freed from such annoying constraints such as the correct spelling of table names:  SELECT_ACTIVE_<FONT color=#ff0000>PRODCUTS</FONT>

  • (cs) in reply to Matt B
    Matt B:
    The best part of this is that the compiler is more likely than not inlining all of their constants into

    public const string SELECT_ACTIVE_PRODUCTS = SELECT * FROM PRODUCTS WHERE PRODUCTS_IS ACTIVE = 1



    forgot the quotes but you get the idea  
  • WTFlet (unregistered) in reply to Code Slave
    Anonymous:

    Let's take this to n'th degree

    public class SqlWords
    {
      public const string SPACE _CHAR= " ";

    //...
      public const string E_CHAR = "E";

    //...
      public const string L_CHAR = "L";

    //....
      public const string S_CHAR = "S";
    }

    public class SqlWords
    {
      public const string SELECT = SPACE_CHAR + S_CHAR + E_CHAR + //...

    <font color="#000000">}</font>

    <font color="#000000">Perhaps that's n-2'th, but there's no way I'm going to hex of binary.</font>



    May your death be long and painful (just like mine after seeing this abomination)
  • Dave (unregistered)

    I can see a future programmer confused as to why SqlWords.ASTERISK is not defined...

    Of course if a majority of their intellectual property was in the SQL statements themselves, if I'm not mistaken, their asinine way of doing the SQL statements would be more easily obfuscated by an obfuscator, because we all know how secure .NET code is!

  • (cs) in reply to Ricky

    Anonymous:
    Thats not really bad.
    In fact, if you do a test -- you will see that using select * is on average faster that specifying all the columns!

    But what if the number of columns changes? There's some stuff (.net typed datasets, among others) that get really upset when the number of columns changes. I've stored multiple values in a column because it was easier to decode values than to patch all the applications that assumed a certain number of columns. Eventually I went on a rampage and removed every "select *" from all the application code and stored procedures I could find. Life is better now.

  • (cs)
    Alex Papadimoulis:
    public const string INNER = " INNER "; public const string JOIN = " JOIN "; public const string INNER_JOIN = " INNER JOIN ";

    [sarcastic-begin] THAT'S not how it's done in a real enterprise application. The right way is,

    public const string INNER = " INNER "; public const string JOIN = " JOIN "; public const string INNER_JOIN = " " + SqlWords.INNER + " " + SqlWords.JOIN + " "; [sarcastic-end]

    :-D

  • georgeblunt (unregistered)

    This was one of the best WTF's I've read on this page.. not because of the code (which of course IS a truly WTF..no doubt), but because of the way the article was written.
    Gotta love this kind of sarcasm :D

  • Ralph Wiggum (unregistered) in reply to Ricky
    Anonymous:
    Thats not really bad.
    In fact, if you do a test -- you will see that using select * is on average faster that specifying all the columns!
    -Ricky


    That's a blanket statement, not always accurate. If your table has 100 columns, and you need 1, selecting the 1 column WILL be faster. If you need 99 columns, selecting * should be faster. Depending on the language, there can be a lot of overhead - JDBC in java for example introduces some horrible overhead for meta columns you're not using anyways.
  • (cs)

    So we all agree here that this is a stupid way of doing things. But let me ask you then: how do you write a generic data access layer for a SQL database? Or do you even do that? I can understand that performing direct queries makes a lot of sense in a desktop application, but how does that scale on a multithreaded web or server application? And how do you automate schema changes? Any thoughts?

  • MadCow42 (unregistered)

    Definately the biggest WTF I've seen here in a while... in most cases you can understand how some newbie, hack, or complete F*&kup might think he's doing something great, but THIS?  How can ANYONE think this is a good way to program anything???

    Wow... the only possible excuse I can even think of is they're paid or measured by the line of code.  They should be castrated and sent on their way anyhow though.

  • Scott (unregistered) in reply to sebmol
    sebmol:
    So we all agree here that this is a stupid way of doing things. But let me ask you then: how do you write a generic data access layer for a SQL database? Or do you even do that? I can understand that performing direct queries makes a lot of sense in a desktop application, but how does that scale on a multithreaded web or server application? And how do you automate schema changes? Any thoughts?


    With alot of code.
  • Willie (unregistered)

    " I've heard from some good sources that the next version of SQL will use the word 'GIMMIE' instead of 'SELECT'."

    Am I the only person who totally wants this to happen?

  • (cs) in reply to anonymous

    Anonymous:
    For some reason or another, I've worked with many DBA's in the past that absolutely forbid the use of stored procedures, views, triggers, etc (basically anything besides tables and indexes).  Basically, the argument is that once you start doing that, you're starting to embed application logic in the database.

    I don't know if I'm for or against this kind of practice.... Has anybody dealt with DBA's who take this stance?

    I take it then your database structure looks like:
     CREATE TABLE [Tables] ( Table_Name VARCHAR )
     CREATE TABLE [Columns] (Table_Name VARCHAR, Column_Name VARCHAR)
     CREATE TABLE [Rows] (Table_Name VARCHAR, Row_Num IDENTITY)
     CREATE TABLE [Values] (Table_Name VARCHAR, Row_Num IDENTITY, Column_name VARCHAR, Value SQLVARIANT)

    Because if it looks anything like that, then you're still embedding some kind of business logi in the database.

  • mikeb (unregistered)

    I call bull!

    There's no way this can be for real. Simply no way.

    Please... this really can't be for real?

  • (cs) in reply to Scott
    Anonymous:
    sebmol:
    So we all agree here that this is a stupid way of doing things. But let me ask you then: how do you write a generic data access layer for a SQL database? Or do you even do that? I can understand that performing direct queries makes a lot of sense in a desktop application, but how does that scale on a multithreaded web or server application? And how do you automate schema changes? Any thoughts?


    With alot of code.


    So you end up writing basically the same code for every application with slight adjustment to the respective problem domain?

    I'm seriously looking for answers because it just doesn't seem right to me. I've been going through ASP.NET/ADO.NET samples and they always go directly through the query without any abstraction and certainly without any caching.
  • More Stored Procedures Please!!! (unregistered) in reply to Jeff S
    Jeff S:
    Anonymous:
    Alex Papadimoulis:

    If you're looking at today's code and thinking, gee, shouldn't these be in stored procedures, or views, or something...



    For some reason or another, I've worked with many DBA's in the past that absolutely forbid the use of stored procedures, views, triggers, etc (basically anything besides tables and indexes).  Basically, the argument is that once you start doing that, you're starting to embed application logic in the database.

    I don't know if I'm for or against this kind of practice.... Has anybody dealt with DBA's who take this stance?


    While today's post is a great WTF, if what you are saying about those DBAs is true, then they have taken the top "WTF" prize for the day.  That might be one of the stupidest things I have ever heard.  Did you really work with *many* of them? That's a scary thought.


    Wow, trying to keep application logic out of a database is the *stupidest* thing you've ever heard?  If there is one property of "enterprise" applications, it is the fact they are often systems that deal with many data sources and services, often performing logic between the disparate sources.  But lets list some reasons to keep the logic out of the database.

    1) Stored procedures tie you to a particular vendor
    2) Application logic in the database has to duplicate logic in the application
    3) Horrible source code control (in every case I've witnessed)
    4) Lack of OO design, hence the term "stored PROCEDURE"
    5) Difficulty migrating to a different database vendor/version
    6) Puts load on the database, which doesn't scale/cluster well since it is the data source of record

    Instead, put the logic in your objects, keep the database as minimal as possible, and certainly use a good persistence tool to ensure the updates and queries are correct.

    I admit, you can instaed take a very data-centric view of things, and many people successfully work under the idea that the database *IS* the application, and everything else is just a GUI/front end.  But this is not very scalable, not Object Oriented at all, and IMHO is only suitable for smaller systems, and certainly not large "enterprise" ;) systems.  All these points can, of course, be debated...

    But wow, this is the *stupidest* thing you've ever heard!?! WTF!!!
  • chazzie (unregistered) in reply to sebmol

    > And how do you automate schema changes?

    Simple.  You DON'T.  You can provide compatibility layers in the form of views and triggers, you can make schema changes through tools that record the schema migration, but there simply isn't any way to make it seamless and automatic.

    The rest goes about the same, just less strongly (dialects and types after all don't change as frequently).  You can't write a perfect generic-for-everything layer any more than you can write a program that does everything with one button push and one line of code that both read "do what I mean". 

    As for scaling, databases are built for that already.  Don't second-guess the database with application logic.  If you end up having to do that, get a better database.

    My captcha says "register".  Is it trying to tell me something?  Yes, that it's broken and now wants me to say "china".  Proving once again that the forum software is the real WTF

  • (cs) in reply to More Stored Procedures Please!!!
    Anonymous:

    Wow, trying to keep application logic out of a database is the *stupidest* thing you've ever heard?  If there is one property of "enterprise" applications, it is the fact they are often systems that deal with many data sources and services, often performing logic between the disparate sources.  But lets list some reasons to keep the logic out of the database.

    1) Stored procedures tie you to a particular vendor
    2) Application logic in the database has to duplicate logic in the application
    3) Horrible source code control (in every case I've witnessed)
    4) Lack of OO design, hence the term "stored PROCEDURE"
    5) Difficulty migrating to a different database vendor/version
    6) Puts load on the database, which doesn't scale/cluster well since it is the data source of record

    Instead, put the logic in your objects, keep the database as minimal as possible, and certainly use a good persistence tool to ensure the updates and queries are correct.

    I admit, you can instaed take a very data-centric view of things, and many people successfully work under the idea that the database *IS* the application, and everything else is just a GUI/front end.  But this is not very scalable, not Object Oriented at all, and IMHO is only suitable for smaller systems, and certainly not large "enterprise" ;) systems.  All these points can, of course, be debated...

    But wow, this is the *stupidest* thing you've ever heard!?! WTF!!!


    Those have been my thoughts exactly. My first larger DB project, I did everything using stored procedures. Actually, I created a web service that basically published those stored procedures and all outside access was done through the web service. The advantage is that you can have one data source regardless of whether your application runs online or on the desktop. While that makes for a very scalable middle-tier, I was stuck with the particular database (SQL Server) I was using and moving to a different database, much less different vendor, was close to impossible.

    So this time around I have a system that is entirely code-driven and executes dynamic queries in the background. The DB schema is automatically updated whenever I make changes to the corresponding objects in the application. Data access is also cached so that I only have to pull data from the db once.

    But my question is still: is this a good way to do things? All the sample code I see everywhere performs direct queries with no caching and no OO whatsoever. Thoughts?

  • DG (unregistered)

    Looking at that made me physically nauseous.  I'm actually still a little queazy.  I probably have to go do something else for a while to get rid of the feeling...

  • anonymous (unregistered) in reply to sebmol

    First, just because you have "ASP.NET/ADO.NET samples and they always go directly through the query" doesn't mean there's "no abstraction or caching going on".  All professional databases, and even some Microsoft ones, use techniques like cursor sharing when processing queries.

     

     

     


     

  • Mihai (unregistered) in reply to Code Slave
    Anonymous:

    Let's take this to n'th degree

    public class SqlWords
    {
      public const string SPACE _CHAR= " ";

    //...
      public const string E_CHAR = "E";

    //...
      public const string L_CHAR = "L";

    //....
      public const string S_CHAR = "S";
    }

    public class SqlWords
    {
      public const string SELECT = SPACE_CHAR + S_CHAR + E_CHAR + //...

    <font color="#000000">}</font>

    <font color="#000000">Perhaps that's n-2'th, but there's no way I'm going to hex of binary.</font>



    Someties this might have a good reason. This is for real:
    =============
    const XMLCh chLatin_A               = 0x41;
    const XMLCh chLatin_B               = 0x42;
    ...
    const XMLCh chLatin_Z               = 0x5A;

    const XMLCh chLatin_a               = 0x61;
    const XMLCh chLatin_b               = 0x62;
    ...
    const XMLCh chLatin_z               = 0x7A;
    =============
    Then used like this:
    static const XMLCh fgXMLCategory[] =
    {
        chLatin_X, chLatin_M, chLatin_L, chNull
    };
    =============
    Q. Can you tell where is this from, and why is done this way?
    A. It is from Xerces, the Apache cross-platform C++ XML parser.
    And it is done this way because it can also run on EBCDIC platforms, where even the 0-128 area does not map directly to Unicode, the way it does in ASCII-based encodings.

  • (cs)

    ...quality-driven approach that focuses on empowering key players to drive-up their core competencies and increase expectations...

     

    That is a true Leveraged Synergy of Dilbertisms

  • (cs) in reply to More Stored Procedures Please!!!
    Anonymous:
    Jeff S:
    Anonymous:
    Alex Papadimoulis:

    If you're looking at today's code and thinking, gee, shouldn't these be in stored procedures, or views, or something...



    For some reason or another, I've worked with many DBA's in the past that absolutely forbid the use of stored procedures, views, triggers, etc (basically anything besides tables and indexes).  Basically, the argument is that once you start doing that, you're starting to embed application logic in the database.

    I don't know if I'm for or against this kind of practice.... Has anybody dealt with DBA's who take this stance?


    While today's post is a great WTF, if what you are saying about those DBAs is true, then they have taken the top "WTF" prize for the day.  That might be one of the stupidest things I have ever heard.  Did you really work with *many* of them? That's a scary thought.


    Wow, trying to keep application logic out of a database is the *stupidest* thing you've ever heard?  If there is one property of "enterprise" applications, it is the fact they are often systems that deal with many data sources and services, often performing logic between the disparate sources.  But lets list some reasons to keep the logic out of the database.

    1) Stored procedures tie you to a particular vendor
    2) Application logic in the database has to duplicate logic in the application
    3) Horrible source code control (in every case I've witnessed)
    4) Lack of OO design, hence the term "stored PROCEDURE"
    5) Difficulty migrating to a different database vendor/version
    6) Puts load on the database, which doesn't scale/cluster well since it is the data source of record

    Instead, put the logic in your objects, keep the database as minimal as possible, and certainly use a good persistence tool to ensure the updates and queries are correct.

    I admit, you can instaed take a very data-centric view of things, and many people successfully work under the idea that the database *IS* the application, and everything else is just a GUI/front end.  But this is not very scalable, not Object Oriented at all, and IMHO is only suitable for smaller systems, and certainly not large "enterprise" ;) systems.  All these points can, of course, be debated...

    But wow, this is the *stupidest* thing you've ever heard!?! WTF!!!


    Sorry, I should have been more clear:

    >> I've worked with many DBA's in the past that absolutely forbid the use of stored procedures, views, triggers, etc (basically anything besides tables and indexes).

    THAT is the stupidest thing I've ever heard.  When something stupid is suggested, even if it has good intentions, it is still pretty stupid.

    Let's try an example for you:

    person #1: "No one should be allowed to use sharpened pencils, because they can be used to kill someone, and killing is bad!"

    person #2: "I disagree with that"

    do you think that this means person #2 thinks killing people isn't bad?
  • Smash (unregistered)

    If "GIMMIE" is the new "SELECT" then they will have to change it to:

    public const string GIMMIE = " GIMMIE ";

    and

    public const string GIMMIE_ACTIVE_PRODCUTS =
        SqlWords.GIMMIE +
        SqlWords.STAR +
        SqlWords.FROM +
        SqlTables.PRODUCTS +
        SqlWords.WHERE +
        SqlColumns.PRODUCTS_ISACTIVE +
        SqlWords.EQUALS +
        SqlMisc.NUMBERS_ONE;

    For the poster that said they wanted GIMMIE to be the new select -- perhaps this notation is for you!  You could re-name the entire SQL syntax!  heh...

    -Smash

  • [Si]dragon (unregistered)
    Alex Papadimoulis:
    In yesterday's post (Bitten by the Enterprise Bug), we learned how vital enterprise application are for proactive organizations leveraging collective synergy to think outside the box and formulate their key objectives into a win-win game plan with a quality-driven approach that focuses on empowering key players to drive-up their core competencies and increase expectations with an all-around initiative to drive up the bottom-line. But of course, that's all a "high level" overview of things. Today, I'd like to dig into the code of enterprise systems a bit.


    Now that was written by a professional.
  • Scott (unregistered) in reply to sebmol
    sebmol:
    Anonymous:
    sebmol:
    So we all agree here that this is a stupid way of doing things. But let me ask you then: how do you write a generic data access layer for a SQL database? Or do you even do that? I can understand that performing direct queries makes a lot of sense in a desktop application, but how does that scale on a multithreaded web or server application? And how do you automate schema changes? Any thoughts?


    With alot of code.


    So you end up writing basically the same code for every application with slight adjustment to the respective problem domain?

    I'm seriously looking for answers because it just doesn't seem right to me. I've been going through ASP.NET/ADO.NET samples and they always go directly through the query without any abstraction and certainly without any caching.


    Try using Generics in 2.0.  You can write a complete Persistence layer that is 100% resusable.

Leave a comment on “Enterprise SQL”

Log In or post as a guest

Replying to comment #:

« Return to Article