按 desc 排序作为 SQL Server Management Studio 的默认选项?

发布于 2024-12-26 10:45:59 字数 136 浏览 2 评论 0原文

有没有办法让 SQL Server Management Studio 默认返回降序行? 每次我通过菜单打开表格(例如通过选择返回所有行),我都会在顶部得到最旧的行。 我知道我可以在 sql 语句中添加“order by desc”,但是这样输入会很烦人:)

Is there some way to make SQL Server Management Studio return rows descending by default ?
Every time i open a table via the menu (for instance by selecting return all rows), i get the oldest rows at the top.
I know i can add 'order by desc' in the sql statement, but typing that is getting annoying :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

狂之美人 2025-01-02 10:45:59

SQL 中没有默认的排序顺序

如果您在顶部看到“最旧的”,那么这可能是引擎检索它的最快方式,因为这就是它在磁盘上的存储方式。

不保证您按此顺序获得它,除非您指定顺序,否则将其视为“无序”!

ORDER BY 是按特定顺序获取结果的唯一方法。

排序可能是一项昂贵的操作,具体取决于指定的表和顺序,因此无序是常态。

There is no default sort order in SQL

If you are seeing "oldest" on top then that may be the fastest way for the engine to retrieve it because that is how it is stored on disk.

You are not guaranteed to get it in this order, consider it "unordered" unless you specify an order!

ORDER BY is the only way to have results in a specific order.

Ordering can be an expensive operation depending on the table and order specified, so unordered is the norm.

心凉怎暖 2025-01-02 10:45:59

JNK说的是100%正确的。

但是,如果您只是希望它正常工作,并且在您打开表时而不是在查询时工作表...

尝试添加聚集索引,第一个索引字段按降序索引。这可能实际上会导致您需要的结果。

(如果您已经在该字段上有聚集索引,请编辑其属性并更改其顺序。)

只有这样的索引对于表的实际使用是友好的,这才是一个明智的想法。如果仅仅为了您的方便而拥有一个在编程上无用的索引,那将是弄巧成拙的;)

What JNK says is 100% correct.

But if you just want it to normally work, and only when you open a table rather than when you query a table...

Try adding a clustered index, with the first indexed field being indexed in descending order. This will likely actually cause what you need.

(If you already have a clustered index on that field, edit its properties and change its ordering.)

This is only a sensible idea if such an index is friendly to the actual use of the table. It would be self defeating to have an index that's useless programatically, just for your convenience ;)

爱人如己 2025-01-02 10:45:59

您无法更改用于从 SSMS 中的上下文菜单生成 SELECT 的现有模板。

值得庆幸的是,SSMS 是可扩展的。这意味着您可以编写自己的扩展来完全执行您想要的操作,或者您可以使用一些现有的解决方案。我推荐 Mladen 的 SSMS 工具包:

http://www.ssmstoolspack.com/

直到最近它还是免费的,并且仍然适用于 2008r2 及更早版本。

You cannot change existing template for generating SELECTs from context menu in SSMS.

Thankfully, SSMS is extensible. This means that you can write your own extensions which can do exactly what you want, or you can use some existing solution. I would recommend Mladen's SSMS Tools Pack:

http://www.ssmstoolspack.com/

It was free until recently, and still is for versions 2008r2 and earlier.

骄兵必败 2025-01-02 10:45:59

查看探查器的输出,似乎查询是动态生成的,因此我不会把希望寄托在可以在某处更改的某些模板上。

/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP 1000 [field1]
      ,[field2]
      ,[field3]
      ,[last_modified]
  FROM [test_database].[dbo].[t_test]

作为替代方案,您可以创建一个小型存储过程,该存储过程采用表的名称和然后返回该表中的数据。假设您的表中有(重复出现的)逻辑来指示记录的“年龄”,那么找出该表的默认顺序应该不会太难。如果您随后将此存储过程链接到热键,您可以轻松地按照您想要的顺序从所述表中获取前 n 条记录。我知道这与在对象资源管理器中获取信息不太一样,但就我个人而言,我从不使用对象资源管理器,而是喜欢通过简单地在查询窗口中选择文本并按 CTRL-3 来获取表的内容。

首先,它看起来像这样。要将

IF OBJECT_ID('p_select_top_100_desc') IS NOT NULL DROP PROCEDURE p_select_top_100_desc 
GO
CREATE PROCEDURE p_select_top_100_desc ( @table_name sysname)
AS

DECLARE @object_id int
DECLARE @order_by_col nvarchar(max)
DECLARE @sql nvarchar(max)

SELECT @object_id = Object_id(@table_name),
       @order_by_col = ''

IF @object_id IS NULL
    BEGIN
        RaisError('Could not find table %s ?!', 16, 1, @table_name)
        Return(-1)
    END

-- find order by column
SELECT TOP 1 @order_by_col = c.name
  FROM sys.columns c
 WHERE c.object_id = @object_id
   AND lower(c.name) in ('modified', 'last_modified', 'change_date', 'crdate', 'etc')

-- if none found, use the identity column
SELECT @order_by_col = c.name + ' DESC'
  FROM sys.columns c
 WHERE c.object_id = @object_id
   AND c.is_identity = 1
   AND @order_by_col  = ''

-- if still none found, use the PK (reverse order)        
SELECT @order_by_col = @order_by_col
        + (CASE WHEN ic.index_column_id = 1 THEN '' ELSE ',' END)
        + c.name 
        + (CASE WHEN ic.is_descending_key = 0 THEN ' DESC' ELSE ' ASC' END)
  FROM sys.indexes i 
  JOIN sys.index_columns ic
    ON ic.object_id = i.object_id
   AND ic.index_id  = i.index_id
  JOIN sys.columns c
    ON c.object_id  = ic.object_id
   AND c.column_id  = ic.column_id
 WHERE i.object_id  = @object_id
   AND i.is_primary_key = 1
   AND @order_by_col  = ''
 ORDER BY ic.index_column_id

-- actual query
SELECT @sql = 'SELECT TOP 100 * FROM ' 
            + @table_name
            + (CASE WHEN @order_by_col = '' THEN '' ELSE ' ORDER BY ' + @order_by_col END)

PRINT @sql
EXEC (@sql)

Return 0

GO

EXEC p_select_top_100_desc 't_test'

其“链接”到热键,您需要转到 Tools \ Customize 菜单,单击 [键盘...] 按钮。展开树中的Keyboard 分支并转到Query Shortcuts 叶。然后,您会看到一个烦人的网格,它允许您将存储过程链接到 CTRL-nbr 组合。请注意,其中一些是固定的+在您配置它并按“确定”后,设置将仅适用于您新打开的查询窗口,现有的查询窗口将适用于“旧”配置。

希望这会有所帮助...

PS:如果您将其命名为 sp_select_top_n_desc 并在 master 数据库中编译它,您应该能够在整个服务器上使用它,而无需在每个数据库中部署它。但是,您可能需要切换到动态 SQL,然后在所有 sys.table 查询前添加 DB_Name() 的输出,否则它可能会在master.sys.columns 表等..这不是你想要的 =)

Looking at the output of the Profiler, it seems the query is generated on the fly so I wouldn't put my hopes upon some template you can change somewhere

/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP 1000 [field1]
      ,[field2]
      ,[field3]
      ,[last_modified]
  FROM [test_database].[dbo].[t_test]

As an alternative you could create a small stored procedure that takes the name of a table and then returns the data from said table. Assuming you have (recurring) logic in your tables that would indicate the 'age' of the records it shouldn't be too hard to figure out a default order for said table. If you then link this stored procedure to a hotkey you can easily get the top n records from said table in the order you wanted. I know it's not quite the same as having the information in the Object Explorer but personally I never use the Object Explorer and rather enjoy getting the content of a table by simply selecting the text in a query window and pressing CTRL-3.

To get you started, it would look something like this

IF OBJECT_ID('p_select_top_100_desc') IS NOT NULL DROP PROCEDURE p_select_top_100_desc 
GO
CREATE PROCEDURE p_select_top_100_desc ( @table_name sysname)
AS

DECLARE @object_id int
DECLARE @order_by_col nvarchar(max)
DECLARE @sql nvarchar(max)

SELECT @object_id = Object_id(@table_name),
       @order_by_col = ''

IF @object_id IS NULL
    BEGIN
        RaisError('Could not find table %s ?!', 16, 1, @table_name)
        Return(-1)
    END

-- find order by column
SELECT TOP 1 @order_by_col = c.name
  FROM sys.columns c
 WHERE c.object_id = @object_id
   AND lower(c.name) in ('modified', 'last_modified', 'change_date', 'crdate', 'etc')

-- if none found, use the identity column
SELECT @order_by_col = c.name + ' DESC'
  FROM sys.columns c
 WHERE c.object_id = @object_id
   AND c.is_identity = 1
   AND @order_by_col  = ''

-- if still none found, use the PK (reverse order)        
SELECT @order_by_col = @order_by_col
        + (CASE WHEN ic.index_column_id = 1 THEN '' ELSE ',' END)
        + c.name 
        + (CASE WHEN ic.is_descending_key = 0 THEN ' DESC' ELSE ' ASC' END)
  FROM sys.indexes i 
  JOIN sys.index_columns ic
    ON ic.object_id = i.object_id
   AND ic.index_id  = i.index_id
  JOIN sys.columns c
    ON c.object_id  = ic.object_id
   AND c.column_id  = ic.column_id
 WHERE i.object_id  = @object_id
   AND i.is_primary_key = 1
   AND @order_by_col  = ''
 ORDER BY ic.index_column_id

-- actual query
SELECT @sql = 'SELECT TOP 100 * FROM ' 
            + @table_name
            + (CASE WHEN @order_by_col = '' THEN '' ELSE ' ORDER BY ' + @order_by_col END)

PRINT @sql
EXEC (@sql)

Return 0

GO

EXEC p_select_top_100_desc 't_test'

To 'link' it to a hotkey you'll need to go to the Tools \ Customize menu, click the [Keyboard...] button. Expand the Keyboard branch in the tree and go to the Query Shortcuts leaf. You then get an annoying grid that allows you to link a stored procedure to a CTRL-nbr combination. Mind that some of them are fixed + after you configure it and press OK the setting will only work for query windows that you newly open, existing ones will work with the 'old' config.

Hope this helps a bit...

PS: if you name it sp_select_top_n_desc and compile it in the master database you should be able to use it all over the server without the need to deploy it in each database. However, you'll probably need to switch to dynamic-sql then en prefix all sys.table queries with the output of DB_Name() as otherwise it will probably look in the master.sys.columns table etc.. which is not what you want =)

夏至、离别 2025-01-02 10:45:59

尽管官方上没有简单线性输入的默认排序顺序,但我得到了令人满意的 DESC 默认排序顺序和 PK 或 IX 排序顺序。假设我对最后一个条目最感兴趣的日志表。

CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL,
CONSTRAINT [PK_tableA] 
PRIMARY KEY CLUSTERED ([DateTime] DESC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]

或者在 SSMS 中...

在此处输入图像描述

Although officially there is no default sort order for the simple linear input I'm getting satisfactory DESC default sort order with PK or IX sort order. Let's say for log tables where I'm interested the most for last entries.

CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL,
CONSTRAINT [PK_tableA] 
PRIMARY KEY CLUSTERED ([DateTime] DESC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]

Or in SSMS ...

enter image description here

薔薇婲 2025-01-02 10:45:59

尝试在该表上创建一个像这样的视图,并在 select 子句或即席查询中使用它

CREATE VIEW dbo.yourTable_vw
AS 
    SELECT TOP 100 PERCENT *
    FROM yourTable
    ORDER BY yourcolumn DESC
GO

Try creating a view on that table like this and use that in your select clause or adhoc query

CREATE VIEW dbo.yourTable_vw
AS 
    SELECT TOP 100 PERCENT *
    FROM yourTable
    ORDER BY yourcolumn DESC
GO
北陌 2025-01-02 10:45:59

实际上,您可以为 ssms 创建一个插件,将新项目添加到对象资源管理器的上下文菜单中。

检查这个问题:在对象资源管理器中创建自定义菜单项

另一种方法是创建一个 SP,该 SP 生成并执行带有主数据库(在所有服务器上)中的 ORDER BY 子句的 select 语句,并将键盘快捷键绑定到该 sp。

Actually you can create an addin for ssms that adds a new item to the object explorer's context menu.

Check this question: Create custom menu item in Object Explorer

Another way is to create an SP which generates and executes the select statement with the ORDER BY clause in the master db (on all servers) and bind a keyboard shortcut to that sp.

感受沵的脚步 2025-01-02 10:45:59

引自 Itzik Ben-Gan 的 Microsoft SQL Server 2012 T-SQL 基础知识 ->第1章->理论背景->集合论:

...当您针对数据库中的表(例如员工表)编写 T-SQL 查询时,您应该将员工集视为一个整体,而不是单个员工。
...
换句话说,对表的查询可以按任何顺序返回表行,除非您明确请求以特定方式对数据进行排序(可能是出于演示目的)。

SSMS 不支持自定义默认 SELECT 语句。如果支持,应该将哪一列放在 ORDER BY 子句之后,考虑到表

  1. 没有像“CreatedDate”这样的列;
  2. 或者其主键是 GUID(顺序不明显)
  3. 或者没有主键或聚集索引

即使 SQL SERVER 有一天能够列出最新数据,这并不是考虑单个行(最新/最旧)的自然方式对着桌子。尝试使用 UPDATE 语句结合 ORDER BY 子句来更新最新数据。

Quoted from Itzik Ben-Gan's Microsoft SQL Server 2012 T-SQL Fundamentals -> Chapter 1 -> Theoretical Background -> Set Theory:

... when you write T-SQL queries against tables in database (such as a table of employees), you should think of the set of employees as a whole rather than the individual employees.
...
In other words, a query against a table can return table rows in any order unless you explicitly request that the data be sorted in specific way, perhaps for presentation purpose.

SSMS doesn't support customized default SELECT statement. If it does support, which column should it put after ORDER BY clause, Considering tables

  1. don't have a column like 'CreatedDate';
  2. or whose primary key is GUID (order is not obvious)
  3. or don't have a primary key or clustered index

Even SQL SERVER will be able to list newest data some day, it's not a nature way to think individual rows (newest/oldest) against tables. Try to use UPDATE statement combined with ORDER BY clause to update newest data.

痴梦一场 2025-01-02 10:45:59

对我来说 - 我首先使用 EF 代码,但每当我创建新表时都执行此操作:
右键单击表,将表脚本设置为->掉落&创建表,编辑 SQL 并将键更改为 DESC,然后运行脚本..完成(没有视图或任何混乱的内容)

for me - I use EF Code first, but do this whenever I create a new table:
Right click table, Script Table as -> Drop & Create table, and Edit the SQL and change the key to DESC, then run the script.. done (no view or anything messy)

‘画卷フ 2025-01-02 10:45:59
create table MYTESTTABLE (
    ID numeric(18, 0) identity(1, 1) not null
    ,COL1 numeric(18, 0) null
    ,COL2 numeric(18, 0) null
    ,COL3 numeric(18, 0) null
    ,COL4 numeric(18, 0) null
 CONSTRAINT [PK_MYTESTTABLE] PRIMARY KEY CLUSTERED 
(
    [ID] DESC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

create table MYTESTTABLE (
    ID numeric(18, 0) identity(1, 1) not null
    ,COL1 numeric(18, 0) null
    ,COL2 numeric(18, 0) null
    ,COL3 numeric(18, 0) null
    ,COL4 numeric(18, 0) null
 CONSTRAINT [PK_MYTESTTABLE] PRIMARY KEY CLUSTERED 
(
    [ID] DESC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文