Looking at the Oracle support, it's similar but nowhere near identical
to what SQL Server would require.

OracleSqlProvider.GetLiteralStatement() is:

        return SqlStatement.Format(
            @"SELECT * FROM ({0}) WHERE {2} > {1}",
            GetLiteralLimit(select, offsetAndLimit), offset, LimitedRownum, 
NewLine);
        return base.GetLiteralLimit(select, limit, offset, offsetAndLimit);

For example, for the original SQL 'SELECT Foo FROM Customers ORDER BY
Foo', then Oracle would generate the new SQL 'SELECT * FROM (SELECT
LimitedTable___.*, rownum Limit___ FROM (Foo FROM Customers ORDER BY
Foo) WHERE rownum <= `limit`) WHERE Limit___ > offset'.

So first of all, SQL Server doesn't seem to have many of these
extensions like Limit___, and secondly SQL Server defined it's
SqlServerSqlProvider.GetLiteralLimit(SqlStatement, SqlStatement) method
to use the TOP function, e.g. 'SELECT TOP(10) Foo FROM Customers ORDER
BY Foo'.  I don't think that the TOP function can be abused to provide
paging services (which is presumably why System.Data.Linq doesn't
generate TOP here.

That said, my original question was, "Is there a higher-level interface
exposed to SQL Vendors to control SQL generation?"  The answer is
apparently No, which is why the SQL Vendor code is full of string
manipulations. :-(

Thanks,
 - Jon

On Tue, 2009-05-05 at 08:47 +0200, Pascal Craponne wrote:

> Hi Jon,
> 
> 
> 
> At a time, the paging support for Oracle was working (it may still
> work, I haven't checked), and it is written just like you would do for
> SQL server.
> 
> 
> Pascal.
> 
> 
> On Mon, May 4, 2009 at 23:12, Jonathan Pryor <[email protected]> wrote:
> 
>         I'm trying to fix the Paging.LinqToSqlPaging01() test for SQL
>         Server.  The reason it fails, unsurprisingly, is because the
>         generated SQL is completely wrong for SQL Server.  It's
>         currently: 
>         
>                 SELECT [CustomerID], [CompanyName], [ContactName], 
> [ContactTitle], 
>                     [Address], [City], [Region], [PostalCode], [Country], 
> [Phone], [Fax]
>                 FROM [dbo].[Customers]
>                 ORDER BY [ContactName] LIMIT 2 OFFSET 1
>         
>         For the same test, SQL Server generates: 
>         
>                 SELECT [t1].[CustomerID], [t1].[CompanyName], 
> [t1].[ContactName], 
>                     [t1].[ContactTitle], [t1].[Address], [t1].[City], 
> [t1].[Region], 
>                     [t1].[PostalCode], [t1].[Country], [t1].[Phone], 
> [t1].[Fax]
>                 FROM (
>                     SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ContactName]) AS 
> [ROW_NUMBER], 
>                         [t0].[CustomerID], [t0].[CompanyName], 
> [t0].[ContactName], 
>                         [t0].[ContactTitle], [t0].[Address], [t0].[City], 
> [t0].[Region], 
>                         [t0].[PostalCode], [t0].[Country], [t0].[Phone], 
> [t0].[Fax]
>                     FROM [dbo].[Customers] AS [t0]
>                     ) AS [t1]
>                 WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
>                 ORDER BY [t1].[ROW_NUMBER]
>         
>         i.e. it uses a nested sub-select and the ROW_NUMBER feature in
>         order to specify the offset.
>         
>         The question: how do I best to support this in DbLinq?
>         
>         Given the current architecture, the solution appears to be to
>         override SqlProvider.GetLiteralLimit(SqlStatement,
>         SqlStatement, SqlStatement, SqlStatement) within
>         SqlServerSqlProvider.  My problem with this is that it would
>         need to be entirely string based, as the select parameter is
>         the entire 'SELECT [CustomerID] ...' command is a single
>         string, resulting in an implementation equivalent to: 
>         
>                 int fromIdx = select[0].Sql.IndexOf("FROM");
>                 string outerSelect = select[0].Sql.Substring(0, 
> fromIdx).Replace("[", "[t0].[");
>                 return SqlStatement.Format("SELECT {0} FROM ({1}) AS [t0] 
> WHERE [t0].[ROW_NUMBER] BETWEEN ...",
>                     outerSelect, select[0].Sql, ...);
>         
>         I don't consider this to be ideal, as if we have e.g. nested
>         selects (db.Where(...).Skip(1).Take(10).Skip(3).Take(2)) I
>         suspect things would break (as we'd get multiple [t0] tables
>         defined).
>         
>         Is there a better solution?  Or is string-based manipulation
>         the only way to go?
>         
>         Thanks,
>         - Jon
>         
>         
>         
>         
>         
> 
> 
> 
> 
> 
> > 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"DbLinq" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/dblinq?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to