diff --git a/builder.go b/builder.go index ffe86d4..5ec653c 100644 --- a/builder.go +++ b/builder.go @@ -358,20 +358,13 @@ func (b *Builder) ToSQL() (string, []interface{}, error) { var err error switch b.dialect { - case ORACLE, MSSQL: + case ORACLE: // This is for compatibility with different sql drivers for e := range w.args { w.args[e] = sql2.Named(fmt.Sprintf("p%d", e+1), w.args[e]) } - var prefix string - if b.dialect == ORACLE { - prefix = ":p" - } else { - prefix = "@p" - } - - if sql, err = ConvertPlaceholder(sql, prefix); err != nil { + if sql, err = ConvertPlaceholder(sql, ":p"); err != nil { return "", nil, err } case POSTGRES: diff --git a/builder_limit.go b/builder_limit.go index 82435da..eeb65ac 100644 --- a/builder_limit.go +++ b/builder_limit.go @@ -67,30 +67,7 @@ func (b *Builder) limitWriteTo(w Writer) error { fmt.Fprintf(ow, " LIMIT %v OFFSET %v", limit.limitN, limit.offset) } case MSSQL: - if len(b.selects) == 0 { - b.selects = append(b.selects, "*") - } - - var final *Builder - selects := b.selects - b.selects = append(append([]string{fmt.Sprintf("TOP %d %v", limit.limitN+limit.offset, b.selects[0])}, - b.selects[1:]...), "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN") - - var wb *Builder - if b.optype == unionType { - wb = Dialect(b.dialect).Select("*", "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN"). - From(b, "at") - } else { - wb = b - } - - if limit.offset == 0 { - final = Dialect(b.dialect).Select(selects...).From(wb, "at") - } else { - final = Dialect(b.dialect).Select(selects...).From(wb, "at").Where(Gt{"at.RN": limit.offset}) - } - - return final.WriteTo(ow) + fmt.Fprintf(ow, " OFFSET %v ROWS FETCH NEXT %v ROWS ONLY", limit.offset, limit.limitN) default: return ErrNotSupportType } diff --git a/builder_select.go b/builder_select.go index c33b386..57bd22d 100644 --- a/builder_select.go +++ b/builder_select.go @@ -21,7 +21,7 @@ func (b *Builder) selectWriteTo(w Writer) error { // perform limit before writing to writer when b.dialect between ORACLE and MSSQL // this avoid a duplicate writing problem in simple limit query - if b.limitation != nil && (b.dialect == ORACLE || b.dialect == MSSQL) { + if b.limitation != nil && b.dialect == ORACLE { return b.limitWriteTo(w) } @@ -115,6 +115,17 @@ func (b *Builder) selectWriteTo(w Writer) error { if _, err := fmt.Fprint(w, " ORDER BY ", b.orderBy); err != nil { return err } + + if b.limitation != nil && b.dialect == MSSQL { + if err := b.limitWriteTo(w); err != nil { + return err + } + } + } + + // limit can only appear after an order by clause + if b.limitation != nil && b.dialect == MSSQL { + return ErrInvalidLimitation } if b.limitation != nil {