diff --git a/src/Umbraco.Core/Persistence/PetaPoco.cs b/src/Umbraco.Core/Persistence/PetaPoco.cs index 63278889a2..88ff456ff6 100644 --- a/src/Umbraco.Core/Persistence/PetaPoco.cs +++ b/src/Umbraco.Core/Persistence/PetaPoco.cs @@ -739,6 +739,11 @@ namespace Umbraco.Core.Persistence /// internal virtual void BuildSqlDbSpecificPagingQuery(DBType databaseType, long skip, long take, string sql, string sqlSelectRemoved, string sqlOrderBy, ref object[] args, out string sqlPage) { + // this is overriden in UmbracoDatabase, and if running SqlServer >=2012, the database type + // is switched from SqlServer to SqlServerCE in order to use the better paging syntax that + // SqlCE supports, and SqlServer >=2012 too. + // so the first case is actually for SqlServer <2012, and second case is CE *and* SqlServer >=2012 + if (databaseType == DBType.SqlServer || databaseType == DBType.Oracle) { sqlSelectRemoved = rxOrderBy.Replace(sqlSelectRemoved, ""); @@ -746,8 +751,16 @@ namespace Umbraco.Core.Persistence { sqlSelectRemoved = "peta_inner.* FROM (SELECT " + sqlSelectRemoved + ") peta_inner"; } - sqlPage = string.Format("SELECT * FROM (SELECT ROW_NUMBER() OVER ({0}) peta_rn, {1}) peta_paged WHERE peta_rn>@{2} AND peta_rn<=@{3}", - sqlOrderBy == null ? "ORDER BY (SELECT NULL)" : sqlOrderBy, sqlSelectRemoved, args.Length, args.Length + 1); + + // split to ensure that peta_rn is the last field to be selected, else Page would fail + // the resulting sql is not perfect, NPoco has a much nicer way to do it, but it would require + // importing large parts of NPoco + var pos = sqlSelectRemoved.IndexOf("FROM"); + var sqlColumns = sqlSelectRemoved.Substring(0, pos); + var sqlFrom = sqlSelectRemoved.Substring(pos); + + sqlPage = string.Format("SELECT * FROM (SELECT {0}, ROW_NUMBER() OVER ({1}) peta_rn {2}) peta_paged WHERE peta_rn>@{3} AND peta_rn<=@{4}", + sqlColumns, sqlOrderBy ?? "ORDER BY (SELECT NULL)", sqlFrom, args.Length, args.Length + 1); args = args.Concat(new object[] { skip, skip + take }).ToArray(); } else if (databaseType == DBType.SqlServerCE) @@ -774,7 +787,7 @@ namespace Umbraco.Core.Persistence throw new Exception("Unable to parse SQL statement for paged query"); if (_dbType == DBType.Oracle && sqlSelectRemoved.StartsWith("*")) throw new Exception("Query must alias '*' when performing a paged query.\neg. select t.* from table t order by t.id"); - + BuildSqlDbSpecificPagingQuery(_dbType, skip, take, sql, sqlSelectRemoved, sqlOrderBy, ref args, out sqlPage); } diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 4c35c90e1b..6cc97bdfb3 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -6,16 +6,11 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Persistence.SqlSyntax { /// - /// Represents an SqlSyntaxProvider for Sql Server + /// Represents an SqlSyntaxProvider for Sql Server. /// - [SqlSyntaxProviderAttribute(Constants.DatabaseProviders.SqlServer)] + [SqlSyntaxProvider(Constants.DatabaseProviders.SqlServer)] public class SqlServerSyntaxProvider : MicrosoftSqlSyntaxProviderBase { - public SqlServerSyntaxProvider() - { - - } - /// /// Gets/sets the version of the current SQL server instance /// @@ -31,7 +26,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax switch (firstPart) { case "13": - _versionName = SqlServerVersionName.V2014; + _versionName = SqlServerVersionName.V2016; break; case "12": _versionName = SqlServerVersionName.V2014; @@ -75,7 +70,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax { var items = db.Fetch("SELECT TableName = t.Name,ColumnName = c.Name,dc.Name,dc.[Definition] FROM sys.tables t INNER JOIN sys.default_constraints dc ON t.object_id = dc.parent_object_id INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND c.column_id = dc.parent_column_id"); return items.Select(x => new Tuple(x.TableName, x.ColumnName, x.Name, x.Definition)); - } + } public override IEnumerable GetTablesInSchema(Database db) { @@ -120,9 +115,9 @@ from sys.tables as T inner join sys.indexes as I on T.[object_id] = I.[object_id inner join sys.all_columns as AC on IC.[object_id] = AC.[object_id] and IC.[column_id] = AC.[column_id] WHERE I.name NOT LIKE 'PK_%' order by T.name, I.name"); - return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, + return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE == 1)).ToList(); - + } public override bool DoesTableExist(Database db, string tableName) @@ -164,7 +159,7 @@ order by T.name, I.name"); switch (systemMethod) { case SystemMethods.NewGuid: - return "NEWID()"; + return "NEWID()"; case SystemMethods.CurrentDateTime: return "GETDATE()"; //case SystemMethods.NewSequentialId: @@ -181,11 +176,11 @@ order by T.name, I.name"); get { return "ALTER TABLE [{0}] DROP CONSTRAINT [DF_{0}_{1}]"; } } - + public override string DropIndex { get { return "DROP INDEX {0} ON {1}"; } } public override string RenameColumn { get { return "sp_rename '{0}.{1}', '{2}', 'COLUMN'"; } } - + } } \ No newline at end of file