Posts Tagged Databases in general

SQL command when inserting M:N association with identity columns in the underlying table

Today I uncovered a magic command from Entity Framework v4 when you create M:N association and the underlying table is defined with both columns as identity (you insert there). I don’t what’s it good for, as this table in fact only stores the two IDs to connect other tables. But somebody may build some logic on identity there, sure.

When I first saw the command, I was completely stunned. I had no idea what’s going on there and whether I see there one or more commands. You can have fun too:

declare @generated_keys table([ID_A] int, [ID_B] int)
insert [dbo].[A_B]
output inserted.[ID_A], inserted.[ID_B] into @generated_keys
default values
select t.[ID_A], t.[ID_B]
from @generated_keys as g join [dbo].[A_B] as t on g.[ID_A] = t.[ID_A] and g.[ID_B] = t.[ID_B]
where @@ROWCOUNT > 0

As an old school guy I was first looking for semicolons and then later tried to decode it by “parsing” the content.

Isn’t it nice… :)

Tags: , ,

Be careful with “not” conditions and nulls in LINQ when querying databases

Today I seen a code with good chance of hard to find mysterious bugs. Let’s start with database table structure we’re going to use for demonstration.

create table NullTest(id int primary key, b bit);

insert into NullTest values (0, 1);
insert into NullTest values (1, 0);
insert into NullTest values (2, null);

If you now try to query this table via LINQ (i.e. LINQ to Entities) you may get surprising results.

foreach (var item in ent.NullTests.Where(x => x.b != true))
{
	Console.WriteLine(string.Format("ID: {0} \t B: {1}", item.id, item.b));
}
Console.WriteLine("===");
foreach (var item in ent.NullTests.AsEnumerable().Where(x => x.b != true))
{
	Console.WriteLine(string.Format("ID: {0} \t B: {1}", item.id, item.b));
}

If you run this code, you’ll get different results.

ID: 1    B: False
===
ID: 1    B: False
ID: 2    B:

What happened? Is the database engine doing something wrong? Or is there a bug in LINQ? Neither of those. In fact both results are correct. The second one (evaluated in .NET on client) is obvious why it’s as is. But what happened in processing of first one (evaluated on database side)? The devil is in NULL logic. Every operation with NULL results in NULL or false if it’s a boolean operation. And this exactly explains the inconsistent result. In .NET null != true is true but in databases it’s false (because of the NULL rules described above).

Thus if you’re writing LINQ query for database, although the impedance mismatch should be hidden from you when using LINQ, you need to take into account different NULL handling in database engines and in .NET (or any common programming language).

Remember the DBNull.Value? That was explicit solution for this “problem”.

Tags: , ,

Foreign keys in conceptual model in Entity Data Model

When I first heard about exposing foreign keys in conceptual model I was getting crazy. It’s the object world, you shouldn’t think this way, in a relational world. On the other hand, working purely in objects can be a pain, especially in web development, and performance problem. Sure, foreign keys can solve you some “problems” (and maybe add some) without tweaking the EntityKey or doing stub entities. Which is hard when dealing with POCO.

But is this a really way to go? Exchange cleanness for comfort.

I don’t know. I was doing the EntityKey magic, and it was magic, because it was not clean. Now I can do it easily, but. For POCO it’s harder, as there’s no EntityKey, but again, you have plain objects – why to deal with foreign keys? What if you move to some non-relational store?

But still one piece is left. The M:N association. Here I cannot use any foreign key, so it’s back to hacking or pure objects. And maybe this is the point. If creating some kind of comfort here for developers, why not to find some way for complete story? Wouldn’t it be nice?

Now I know (see how good is trying to write your own ideas). I don’t like the current concept of FKs. It’s too easy, and just too replicating behavior of relational world. But if there would have been some improvement for the other types of associations to cover all types in uniform way, I would vote for it with both my hands. Although still saying that it’s not nice but acceptable, as relational databases – it seems – will be with us for sure next couple of years.

Tags: ,

FBCon 2009 München – .NET + Firebird will be there

Next Firebird conference is coming. This year in München, Germany. I’ve never been in München though it’s pretty close to Czech Rep. thus I’m looking forward.

You can find info about conference at firebird-conference.com. I’ll be speaking there too, hence if you’re interested in Firebird and .NET you should definitely come. Every day I have one session. I’ll be covering new (2.5+) protocol implementation in .NET client for Firebird 2.1, Entity Framework support (also new in 2.5) and finally you’ll see how to create Windows phone (formely PocketPC, …) application and accessing Firebird database.

And the conference will be also great place to meet people you know from list etc. and talk face to face about your Firebird related problems, challenges and solutions. If you have any specific need to show (related to my three sessions) feel free to drop line in comments.

Tags: , , , , , , ,

Unique constraint on MS SQL?!

I have a strong feeling that MS SQL knows I don’t like it. I don’t say it’s a bad database, but sometimes it’s really “interesting”. ;)

OK, so what I faced this time? Let’s start with basic facts. The NULL value in database is a special value. NULL and NULL is again NULL, NULL and False is again NULL and NULL isn’t equal to NULL. Two days ago I was creating a chain of records in database (which isn’t too relationalish, but …) and I needed unique constraint on one column. No problem you may think. So did I. But not in MS SQL.

Check this example:

1> create table test(id int primary key, foo int);
2> create unique index idx_text on test(foo);
3> go
1> insert into test values (1, null);
2> go

(1 rows affected)
1> insert into test values (2, null);
2> go
Msg 2601, Level 14, State 1, Server X2-001\SQLEXPRESS, Line 1 Cannot insert duplicate key row in object 'dbo.test' with unique index 'idx_text '.
The statement has been terminated.

What a mess! Looks like somebody in MS SQL engine team thinks NULL == NULL. After some railing, testing on Firebird and asking my friend about Oracle, I googled: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=299229. Looks like I’m not alone; feeling better. ;)
Luckily I’m working on MS SQL 2008 and I can use filtered indices. Created unique index with where clause where <column> is not null and I’m done. But boy that was a bitter finding. Hope I’ll not be punched to the face with these basics again in an at least two months.

Tags: , , ,

Transactions are making me crazy

I hate transactions, ACID and all the stuff. Really, I do. No, I don’t, it’s a great to have challenges with this kind of thinking. But in last two projects (in a row) I had similar problem and transactions were making it even more challenging.

The simple version is that I needed to have data constraint in database (did I mention that I’m constraint freak?) based on not the row itself, but the data in the table and related tables. If you’ve play with transactions you know this is a problem. Either you may run in read uncommitted mode, see everything and if somebody will do something violating the constraint, even if it will be rolled back, you will start screaming and throwing exceptions or you will use serializable and, to be sure, explicit locking in every piece of trigger or stored procedure code, which is good for you but not for performance. Choose whatever fits your needs better, but right now, for this particular scenario I wish the transactions gone and pretending there’s no isolation from others at all (and with decent performance too).

I know it’s impossible, because interactions in database are making creating some general purpose “command/constraint” tough. And what’s good for one case is definitely not suitable for other.

Anyway maybe with more work done on distributed systems and clouds, where even the simple constraints are interesting to enforce, we’ll find some good way how to solve this. ;)

Tags:

Force Entity Framework to optimize/simplify huge queries

When you write huge (I mean really huge, not a ~300 lines baby) complex query you may experience, that the generated query looks (well) suboptimal. The reason is that after some line the Entity Framework will gave up on optimization and simply throws it as is. To turn this off and force to simplify it whatever query it is you can add this into your app.config, as Kati Iceva pointed in MSDN forums.

<system.diagnostics>
  <switches>
    <add name="System.Data.EntityClient.IgnoreOptimizationLimit" value="1" />
  </switches>
</system.diagnostics>

But also take into account that this may end up with a significant time spent in EF’s code and at the end the query will be still too big for the store to run it or the store would do better job optimize it. Thus the overall time may be same or even worse (= use carefully).

It’s also worth, if you’re able to write the query a lot simpler, to discuss this in MSDN forums, so the code in EF can be improved.

Tags: ,

Eager loading cost – another stuff to consider

Julie Lerman made a great post about The cost of eager loading in Entity Framework. And everything there is true, in fact if you take my Entity Framework training, you will know that with all reasons and you’ll also learn performace improvements you may incorporate into your solution.

I want to make some small addition to this post. There’s another stuff to think about. That’s the cost of processing query on server.

You should always consider the cost of parsing, compiling, finding execution plan etc. the query on server as well as fetching the intermediate data (which may cause cleaning up caches etc.). Thus sometimes (and we’re back to balance as Julie said) it’s better to issue couple of smaller (not so complex) queries, rather than one huge query.

Tags: ,

Mapping stored procedures that are returning non-entity result in EDM

If you want to map stored procedure you have three options what the stored procedure can return. Nothing, some scalar value and entity. The problem is that sometimes you have SP that’s returning some data, but not some entity. The way to solve this is to create entity with same shape as the SP is returning. But the problem is, that this entity type needs to be mapped to something, probably table. Else the model is not valid. The good message is, that you can create fake table in SSDL and use it. :) But it’s a pain to create it, because you have to deal with XML directly and create not only the fake table with proper structure, but also entity set. When reading pre-prelease :) version of Julie Lerman’s wonderful book Programming Entity Framework there was a sigh about some tool to automate the process. Well today I have some time, to create rough tool to create some kind of this tool.

static void Main(string[] args)
{
    #region Initial checking
    if (args.Length != 3)
        return;

    string tablenameToFake = args[0];
    string emdxFile = args[1];
    string fileForSaving = args[2];

    if (!File.Exists(emdxFile))
        return;
    if (File.Exists(fileForSaving))
        return;
    #endregion

    XDocument xdoc = XDocument.Load(emdxFile);

    const string CSDLNamespace = "http://schemas.microsoft.com/ado/2006/04/edm";
    const string SSDLNamespace = "http://schemas.microsoft.com/ado/2006/04/edm/ssdl";
    XElement csdl = xdoc.Descendants(XName.Get("Schema", CSDLNamespace)).First();
    XElement ssdl = xdoc.Descendants(XName.Get("Schema", SSDLNamespace)).First();

    XElement csdlItem = csdl.Elements(XName.Get("EntityType", CSDLNamespace))
        .Where(x => x.Attribute("Name").Value.ToUpperInvariant() == tablenameToFake.ToUpperInvariant()).FirstOrDefault();
    if (csdlItem == null)
        return;

    Func<string, string> getStoreType = (string csdlTypeName) =>
        {
            // Use some information from store provider or use some dummy or extend this switch using common SQL names?
            switch (csdlTypeName)
            {
                case "Int16":
                case "Int32":
                case "Int64":
                    return "int";
                case "String":
                    return "varchar";
                default:
                    return "blob";
            }
        };

    #region New EntityType creation
    XNamespace n = SSDLNamespace;
    XElement tableToFake = new XElement(n + "EntityType", new XAttribute("Name", tablenameToFake));

    var keys = from x in csdlItem.Element(XName.Get("Key", CSDLNamespace)).Elements(XName.Get("PropertyRef", CSDLNamespace))
               select new XElement(n + "PropertyRef",
                   new XAttribute("Name", x.Attribute("Name").Value));

    tableToFake.Add(new XElement(n + "Key", keys.ToArray()));

    var columns = from x in csdlItem.Elements(XName.Get("Property", CSDLNamespace))
                  select new XElement(n + "Property",
                      new[] {
                          new XAttribute("Name", x.Attribute("Name").Value),
                          new XAttribute("Type", getStoreType(x.Attribute("Type").Value)),
                          new XAttribute("Nullable", (x.Attribute("Nullable") != null ? x.Attribute("Nullable").Value : "true"))
                      });

    tableToFake.Add(columns.ToArray());
    #endregion

    #region EntitySet for new entity
    XElement someEntitySet = ssdl.Element(XName.Get("EntityContainer", SSDLNamespace)).Element(XName.Get("EntitySet", SSDLNamespace));
    XElement newEntitySet = new XElement(someEntitySet);
    newEntitySet.Attribute("Name").Value = tablenameToFake;
    newEntitySet.Attribute("EntityType").Value = ssdl.Attribute("Namespace").Value + "." + tablenameToFake;
    #endregion

    ssdl.Add(tableToFake);
    ssdl.Element(XName.Get("EntityContainer", SSDLNamespace)).Add(newEntitySet);
    using (XmlTextWriter writer = new XmlTextWriter(fileForSaving, Encoding.Default))
    {
        xdoc.WriteTo(writer);
    }
}

This code simply looks for entity you specified and makes the appropriate items in SSDL. It’s very rough, especially datatypes for table are scamped ;) , but you can extend it youself with your favourites. Or maybe better use some information from store provider. Anyway the basic idea is here, if you extend dataypes, it will work well for this stuff. Mapping should be done by you in designer, although because column names are same as entity’s, you only need to choose right table name, rest will be done by the designer. And of course, when updating model from database, these changes are lost.

Comments are welcome.

Tags: , , ,

Firebird ADO.NET Data Provider 2.5.0 Beta 1 for .NET 3.5/2.0 [with Entity Framework support]

I’m pleased to announce 2.5.0 Beta 1 for .NET 3.5/2.0 [with Entity
Framework support] version. It contains several bugfixes as well as
brand new Entity Framework support (still beta!). Looking forward to
your feedback.

Binary as well as sources can be downloaded from
http://www.firebirdsql.org/index.php?op=files&id=netprovider.

Tags: , , , , , , ,

Birthdates and looking for birthdays

Today there was a question in db section in builder.cz forum. In essence, how to show people having birthday today or in couple of days if I have a birthdate. Well the solution I’ll show you here is in Firebird syntax, but shouldn’t be a problem to rewrite it to any other platform you like.

So the solution is like this (of course, you can find many other ways how to solve it):

select dateadd(year, datediff(year, birthdate, current_date), birthdate) from
(
select cast('1.2.1993' as date) as birthdate from rdb$database
);

OK, what’s the idea behind. First step is to get difference between these dates in year. Then, using the dateadd function to prevent some mismatch in date arithmetics (i.e. leap years), to add this difference to birthdate. Now you have it in “current year”, so it’s easy to test whether it’s between today and today + x. To improve speed, you can create computed index for this expression.

Tags: ,

How to use custom objects with associations in Entity Framework

Today I had some time and I spent it playing with associations mapping on custom objects. Adding new objects is easy. It’s what you already know. The only one new part is work with associations and navigation properties. But as always when you stuck you can generate dummy EDMX file and look at the result. :-)

You can start from scratch and create all classes and so on as in previous article. But I’ll start where I ended, it’s little bit faster.

First thing you have to create is new class, related to our Product class. I’ll create ProductSize class that will hold info about the size of product (don’t try to find something useful on this, it’s just a simple example). The class will contain only ID and Size property. You can take inspiration from previous article, it’s almost same. What you have to add is an IEntityWithRelationships interface implementation to both classes. It’s same for both. This interface forces you to implement RelationshipManager member.

RelationshipManager IEntityWithRelationships.RelationshipManager
{
  get
  {
    if (_relationships == null)
      _relationships = RelationshipManager.Create(this);

    return _relationships;
  }
}

Now you have to either edit CSDL, MSL and SSDL files by hand (if your night reading is some *.edmx file) or generate these again using EdmGen/EdmGen2 and remove any unnecessary lines. Also you can rename some items to match your needs and class members (i.e. if you have NavigationProperty one-to-many on one side would be probably plural and on other side singular). Good checkpoint after this is to run EdmGen with ValidateArtifacts mode to uncover any problems.

After this you have to modify class that you get in previous article from custom tool usage. You have to apply EdmRelationshipAttribute using the assembly prefix, because it has AttributeTargets.Assembly as usage. When you use custom tool, it will be generated for you. When first trying to do the mapping I forgot about it and I lost half an hour of my time. :-)

[assembly: EdmRelationship("CustomClasses_EDM", "FK_Products_ProductSizes", "ProductSizes", RelationshipMultiplicity.One, typeof(CustomClasses_EDM.ProductSize), "Products", RelationshipMultiplicity.Many, typeof(CustomClasses_EDM.Product))]

Now you only need to add navigation properties in your custom classes. Of course, you can add some properties to your ObjectContext class, similar to Products.

OK, first, apply EdmRelationshipNavigationProperty attribute to your navigation properties. For my Product object and ProductSize property it looks like this.

[EdmRelationshipNavigationProperty("CustomClasses_EDM", "FK_Products_ProductSizes", "ProductSizes")]

Let’s do the getter. You have to get RelationshipManager and use GetRelatedReference method. For my Products ⇒ ProductSizes direction you should end up with:

get
{
  return ((IEntityWithRelationships)(this)).
    RelationshipManager.
    GetRelatedReference<ProductSize>("CustomClasses_EDM.FK_Products_ProductSizes", "ProductSizes").Value;
}

For other direction use the GetRelatedCollection method and no Value is used. The setter for Products ⇒ ProductSizes direction is just about assigning value to Value. For ProductSizes ⇒ Products it’s little bit different. You have to use InitializeRelatedCollection method to set new value.

((IEntityWithRelationships)(this)).
  RelationshipManager.
  InitializeRelatedCollection<Product>("CustomClasses_EDM.FK_Products_ProductSizes", "Products", value);

And maybe it’s good idea to check for nulls, because it’s not allowed to put it there (again, just fine-tuning).

Now when you try to run the code like:

var q = from p in ctx.Products
         where p.ID < 200
         select p; 

foreach (Product p in q)
{
  Console.WriteLine(p.Name);
  Console.WriteLine("\t" + p.ProductSize.Size);
}

You got exception. Yeah, lazy loading. You have to use, for example (Entity Framework Include with Func):

var q = from p in ctx.Products.Include("ProductSize")
         where p.ID < 200
         select p;

foreach (Product p in q)
{
  Console.WriteLine(p.Name);
  Console.WriteLine("\t" + p.ProductSize.Size);
}

Using custom objects and associations with Entity Framework isn’t hard too. You generate three files from database, change it (which is maybe the hardest part – to match database to your objects) and small changes in objects. And you’re done.

Yet again, with POCO and persistence ignorance it will much easier. But it isn’t impossible now.

See also: How to map your custom objects in Entity Framework

Published on Databazovy Svet

Tags: , , , ,

How to map your custom objects in Entity Framework

Well, generating EDMX file from database and letting Visual Studio to generate all the objects is easy. But sometimes you have your custom objects with custom logic. How to solve this? In version 1 of Entity Framework this isn’t easy. It’s possible, but not easy. The good news is, that for version 2 there is huge amount of work on POCO (Plain Old CLR Objects) with persistence ignorance.

With current version you have, in general, two possible choices. The “easier” way is to derive from special object EntityObject. Anyway, this is probably what you don’t want, because you’re probably deriving from your own objects (and as we know multiple inheritance isn’t possible in C#). The other way is to implement some interfaces. It’s not so straightforward, but, at least in my opinion, more practical.

In our simple example we’ll be neither using complex types (it’s not so hard to add it) nor any associations (I’ll cover this later in other article). Let’s start with our class, I’ll call it Product and it’ll be very simple.

public class Product
{
  private int _id;
  private string _name;
  private int _price;

  public int ID
  {
    get { return _id; }
    set { _id = value; }
  }

  public string Name
  {
    get { return _name; }
    set { _name = value; }
  }

  public int Price
  {
    get { return _price; }
    set { _price = value; }
  }
}

As you can see, the class is really simple. You can imagine some logic i.e. on price or on name length. To make this object “tasty” for Entity Framework infrastructure you have to implement only one interface. It’s called IEntityWithChangeTracker. For associations support you should implement also IEntityWithRelationships. There’s also IEntityWithKey interface that forces you to implement EntityKey to improve performance and decrease memory usage. It’s just cherry on a pie.

The first noted interface implementation is pretty easy. You’ll just implement one method in easy way.

void IEntityWithChangeTracker.SetChangeTracker(IEntityChangeTracker changeTracker)
{
  _changeTracker = changeTracker;
}

With complex types you have also set change tracker for these using SetComplexChangeTracker method.

To make change tracker working, we need to slightly change our setters. The setters should look like this for Name property.

set
{
  if (_changeTracker != null)
    _changeTracker.EntityMemberChanging("Name");

  _name = value;

  if (_changeTracker != null)
    _changeTracker.EntityMemberChanged("Name");
}

Pretty simple, isn’t it? The last thing you have to change in your class is to add EdmScalarProperty attribute to ID, Name and Price members. That’s all you have to do with the class.

Now comes the tricky part (don’t be scared it’s not heavy magic :-) ). First you need to get SSDL, MSL and CSDL files. These files contain store-schema, mapping and conceptual-schema definition. Although you can write these files by hand, using some tool is much faster. The easiest way is to generate these using EdmGen (or maybe EdmGen2). EdmGen is standard part of Entity Framework. Just use FullGeneration mode and provide /connectionstring and /project parameters. This gives you five files in result. Delete the two with *.cs extension, you don’t need it. With EdmGen you get complete mapping for whole database so you have to delete some unnecessary stuff. Leave there only lines related to Products table (or whatever your table named is). If you don’t understand content of these files, the best way is to generate *.edmx file in Visual Studio only for our table and look at the result (EDMX file is in fact just CSDL, MSL and SSDL together plus some other stuff. You can use i.e. EdmGen2 to extract these files. But EdmGen2 isn’t standard part of Entity Framework.) right-clicking on the file and choosing Open With... and XML Editor. After this tricky part add these files to your project. On CSDL file open Properties and use for Custom Tool EntityModelCodeGenerator. This generates you new file under CSDL file. Copy content into new file and remove the Custom Tool definition. This new file contains implementation of ObjectContext class and also Products class. You can delete Products class (or class for your table), because we have ours. The last step is to replace occurrences of Products that has been removed, by Product, which is our class (you can use Products (plural), where it makes sense, of course). So the result can look like this.

public global::System.Data.Objects.ObjectQuery<Product> Products
{
  get
  {
    if ((this._Products == null))
    {
      this._Products = base.CreateQuery<Product>("[Product]");
    }
    return this._Products;
  }
}

private global::System.Data.Objects.ObjectQuery<Product> _Products;

public void AddToProducts(Product product)
{
  base.AddObject("Product", product);
}

You can also change the first constructor, if you’re interested.

After this you can use standard ways to query or update the Products table. You have to provide “entity frameworkish” connection string to make it work. The first option is to embed CSDL, MSL and SSDL files into resources and use res://<assemblyFullName>/<resourceName> specification in connection string (more info on http://msdn.microsoft.com/en-us/library/cc716756.aspx) or simply copy these three files into some folder and use path. My choice was the second (copying files into same folder as executable), so my code looks like (using MS SQL Express):

CustomClasses_EDMContext ctx = new CustomClasses_EDMContext("metadata=CustomClasses_EDM.csdl|CustomClasses_EDM.ssdl|CustomClasses_EDM.msl;provider=System.Data.SqlClient;provider connection string=\"Data Source=.\\sqlexpress;Initial Catalog=test;Integrated Security=True\"");

var q = from p in ctx.Products
where p.ID < 200
select p;

foreach (Product p in q)
{
  Console.WriteLine(p.Name);
  p.Name = p.Name + "R";
}

ctx.AddToProducts(new Product() { Name = "New Product", Price = 999 });

ctx.SaveChanges();

When you try to run this example, you’ll be able not even to enumerate items in table (products), but also to update, add etc. it.

It’s not as fast as using designer, you have to do some manual work (but I think you can write some tool to automate it and also EdmGen2 will help), however you’re using your custom objects (without rewriting these completely).

The work on POCO and persistence ignorance in version 2 of Entity Framework will be a step forward, no doubts, but this isn’t too bad isn’t it? :-)

See also: How to use custom objects with associations in Entity Framework

Published on Databazovy Svet

Tags: , , , ,

Firebird Developers’ Day 2008

Podobně jako minulý rok, i letos jsme se rozhodli uspořádat Firebird Developers’ Day. Loni místnost trochu přetékala, takže doporučuju registrovat včas.

Níže je oficiální program.

Konference Firebird Developers’ Day 2008 se uskuteční 16. října 2008 na pražské Přírodovědecké fakultě Univerzity Karlovy, Albertov 6, v sále označovaném jako Věž. K dispozici bude v den konání konference navigace.

Registrace začíná v 10.00 (začátek jsme posunuli, abychom vyšli vstříc mimopražským účastníkům) a vstup je zcela zdarma, podmínkou je pouze registrace. Budete-li mít jakékoli problémy s registračním formulářem, kontaktujte nás, prosím, na adrese fdd2008reg@dbsvet.cz.

Počet míst je omezen, proto doporučujeme v případě zájmu zaregistrovat se co nejdříve. Celý program je v českém jazyce. Každý účastník navíc obdrží hodnotnou databázovou publikaci z produkce společnosti Computer Press (ta o Firebirdu a InterBase od Pavla Císaře asi na všechny nevyjde, ale budou k dispozici stejně kvalitní).

Po vlastním programu bude následovat neformální setkání přednášejících a účastníků ve vhodném restauračním zařízení.

10:00 – 10:30 Registrace
10:30 – 10:35 Zahájení a úvodní slova
10:35 – 11:05 Co nového okolo Firebirdu?
Jiří Činčura, nezávislý IT specialista
11:10 – 11:40 The Crash – krátké pojednání o jednom
přechodu z VMware na fyzické železo
Slavomír Skopalik, Elekt Labs
11:45 – 12:35 Firebird a Python
Pavel Císař, IBPhoenix
12:35 – 13:00 Přestávka
13:00 – 13:30 11 let s “Ptákem Ohnivákem” – případová studie nasazení
databáze Firebird v ERP systémech firmy ABRA Software
Martin Shayna, ABRA Software
13:35 – 14:25 Entity Framework a FirebirdClient
Jiří Činčura, nezávislý IT specialista
14:30 – 15:00 OLAP – Jak postupovat při návrhu OLAP dotazů tak, aby byly
efektivní (krátký úvod do problematiky, úzká místa, sestavení dotazu)
Pavel Mazáč, Elekt Labs
15:00 – 15:30 Přestávka
15:30 – 16:20 Zálohování Firebird databází – desetkrát a pokaždé jinak
Ivan Přenosil, nezávislý IT specialista
16:25 – 17:05 PostgreSQL v roce 2008
Pavel Stěhule, nezávislý IT specialista
17:10 – 17:45 Panelová diskuse na téma Firebird a bezpečnost
17:45 – 17:55 Losování cen, zakončení

Tags: , , , ,

Microsoft Sync Framework v1.0

MS Sync Framework v1.0 is ready for download.

Tags: , , ,

Running program from trigger, SP, …

This article was originally created for
Databazovy Svet (in Czech) and covers a little bit more about this topic. This shortened version is focused only on solutions for Firebird, without any other stuff.

Sometimes I see question(s) in forums, groups, lists about ability to run program from trigger or better to say perform some action done by external program. Well you can create many of possible solutions, working best for your case. But I’ll cover two “special” features available in Firebird that can help you with this.

First, very elegant, option is to use events sent to clients subscribed to these. Every good connecting layer supports events – at least I can say, that Delphi, .NET, PHP, C/C++ works. Event is an identifier sent to subscribed clients from database server using some negotiated channel (i.e. similar to channel for sending commands). On the database side we’ll use
POST_EVENT <identifier>
, where identifier is any string (maximal length 78 characters). Application should subscribe for consuming event with same identifier. For example in .NET/C# the code will look like this:

FbRemoteEvent revent = new FbRemoteEvent(connection);
revent.AddEvents(new string[] { "new_order" });

// Add callback to the Firebird events
revent.RemoteEventCounts += new FbRemoteEventEventHandler(EventCounts);

// Queue events
revent.QueueEvents();

static void EventCounts(object sender, FbRemoteEventEventArgs args)
{
    Console.WriteLine("Event {0} has {1} counts.", args.Name, args.Counts);
}

This solution is very neat and event are made for this kind of tasks. The handling application can run on another machine. Disadvantage is, that events are sent on commit. About rolled back transactions – if you’re interested in – you’ll not be notified. Same story with some payload, you cannot add to event some data. So if you need to send some data you have to use some kind of timestamps, flags etc.

The other solution is coming with, kind of, opposite (dis)advantages. The main idea is to use program modules (*.dll/*.so) compiled into User Defined Functions – UDFs. This module may contain any code, written in any language with
stdcall
calling convention support – C/C++, Delphi, FreePascal. Taking into account, that this code is running in server context and is blocking any subsequent execution, it’s good to keep this code really simple – KISS = Keep It Simple Stupid. For our example is suitable to make the UDF only sending some signal to another application and this application will do the action(s). The advantage of this solution is, that you can hand over the data too. Function calling is done immediately. So it’s obvious, that also data from transaction, that can be rolled back later will be processed.

Hey, that’s all. :) No more tricky stuff, just these two simple solutions. My advice is to first use events and then try to hack UDFs. Events are much better for this.

Tags: ,

Validace dat – kam jak kde proč

Mám rád všelijaká omezení. Jako správně postižený databázista mám constrainty všude. Čistá a konzistentní data mám prostě rád (ano, při upgradech vyměknu a něco někde povolím/odstraním :) ) Na druhou stranu nesnáším validace a omezení. [8-|] Člověk musí zobrazovat pěkné chybové hlášky, nejlépe ještě před odesláním dat na server. To znamená mít validace a omezení nejen pěkně v databázi, ale i někde poblíž ksichtu aplikace. A to mě nebaví, musíte psát ty samé validace a případně obalovat chyby/vyjímky z DB do konkrétních vyjímek, které je možné patřičně zpracovat. Poté co člověk navrhne hromadu foreign key a check constraintů a čert ví čeho ještě, musí to podat i nějak userovi, tedy user-friendly – překvapivě většině nestačí chybová hláška z DB nebo nějaká obecná věta ;) . Ach jo. Škoda že není nějaký generátor, který by uměl tohle všechno vyřešit podle databáze sám.

Tags:

UNION and UNION ALL in LINQ to SQL

When you need to hook up two results in LINQ to SQL you will probably first try the method Union. It generates “standard” union (i.e. select a, b, c from x union select e, f, g from y), which is OK. But if you know the difference between union and union all (union (without all) is filtering duplicates in result, so it can be slower) you may want to use union all (for example you know that results are distinct or you want duplicates). So, you will need another method. It’s called little bit “non-SQL” :) Concat (at least it took me few minutes to find it, but the name makes sense). Using this method you get result with union all, so you can save some processing and speedup returning result.

Summary: UNION ALL ==> Concat
UNION ==> Union

Tags: , ,

MS SQL delete a insert

MS SQL je divnej :) [tak, to to schytám]. Přepisoval jsem něco do Entity Frameworku pro Firebird ze samples, kde se samozřejmě pracuje s MS SQL. Ačkoli specifikace SQL (SQL’92) hovoří jasně o tom, jak má vypadat insert a delete statement, MS SQL musí mít něco extra (a určitě to má super důvod).

Insert je definován jako “INSERT INTO <table name> <insert columns and source>” MS SQL vesele pobere i verzi bez “INTO”. Podobně jako delete (s podmínkou) je definován “DELETE FROM <table name> [ WHERE <search condition> ]” MS SQL opět vesele pobere i verzi bez “FROM”.

Technicky vzato to může být jedno, každá DB má své nuance. Nicméně tyto základní věci by podle mě, mohly být stejné – už jen aby to každý dokázal lehce přečíst, vzít a použít jinde. Ale třeba jsem moc upjatý …

Tags:

"Praxe": Zařazení něčeho do kategorií

Dneska jsem se dostal opět k velmi vtipnému řešení problému v relační databázi (to jsem to hezky napsal, ale ve skutečnosti jde o prasácky vyrobenou tabulku(y) vyústivší v prasácké selecty).

No schválně. Jak budete řešit přiřazení položky do kategorií? Ano, například jednoduchá tabulka (id_item, id_kategorie). Ale to je řešení běžné… Vskutku vtipné řešení, je přidat k položce sloupec, který obsahuje znakem, např. ‘|’, oddělené hodnoty. Pak máte velmi výkonný select ‘SELECT * FROM tabulka WHERE (kategorie LIKE ‘%|12345|%’) ORDER BY id’ (nad “select *” se již nepozastavuji).

No to si pak užijeme legrace s sql serverem, že? ;)

Tags: