Add category by DB

upload categories by DB

--step1 check account_combination
select cost_account_cob,clear_account_cob,
accumulated_deprn_cob,a.* from setup_categories_all a
where not exists ( select 'challenge' from gl_code_combinations_kfv where concatenated_segments= a.accumulated_deprn_cob)

create table SETUP_CATEGORIES_ALL
(
  CODE_COMBINATION      VARCHAR2(84),
  BOOK_NAME             VARCHAR2(30),
  DEPRN_METHOD          VARCHAR2(20),
  DEPRN_LIFE            NUMBER,
  DEPRN_PRORATION       VARCHAR2(20),
  RETIREMENT_PRORATION  VARCHAR2(20),
  COST_ACCOUNT          VARCHAR2(20),
  CLEAR_ACCOUNT         VARCHAR2(20),
  COST_ACCOUNT_COB      VARCHAR2(200),
  CLEAR_ACCOUNT_COB     VARCHAR2(200),
  EXPENSE_ACCOUNT       VARCHAR2(20),
  ACCUMULATED_DEPRN     VARCHAR2(20),
  ACCUMULATED_DEPRN_COB VARCHAR2(200),
  CIP_COST_ACCOUNT      VARCHAR2(20),
  CIP_CLEAR_ACCOUNT     VARCHAR2(20),
  CIP_COST_ACCOUNT_COB  VARCHAR2(200),
  CIP_CLEAR_ACCOUNT_COB VARCHAR2(200),
  MAJOR                 VARCHAR2(20),
  MINOR                 VARCHAR2(20),
  SUB                   VARCHAR2(20),
  CAP                   VARCHAR2(20),
  percent_salvage_value number
);

 


select * from FND_ID_FLEX_STRUCTURES_VL  where id_flex_structure_code ='GECI_ACCOUNTING_FLEXFIELD'
-----chart_of_account = 50349

declare
  v_category_id number;
  cursor categories is
    select * from setup_categories_all a where not exists (select 'challenge tang' from FA_CATEGORIES_B fc,FA_CATEGORY_BOOKS fb
where fc.category_id=fb.category_id
and fc.segment1 = upper(a.major)
and fc.segment2 = upper(a.minor)
and fc.segment3 = upper(a.sub)
and fc.segment4 = upper(a.cap)
and fb.book_type_code = a.book_name ) ;

begin
  for C1 in categories loop
    begin
      select category_id
        into v_category_id
        from FA_CATEGORIES_B
       where segment1 = upper(C1.major)
         and segment2 = upper(C1.minor)
         and segment3 = upper(C1.sub)
         and segment4 = upper(C1.cap);
      dbms_output.put_line(C1.major || '.' || C1.minor || '.' || C1.sub || '.' ||
                           C1.cap || ' Category ID: ' || v_category_id);
    exception
      when others then
        v_category_id := null;
       --- dbms_output.put_line('v_category_id is null');
    end;
    if v_category_id is null then
      select FA_CATEGORIES_B_S.nextval into v_category_id from dual;
      dbms_output.put_line(C1.major || '.' || C1.minor || '.' || C1.sub || '.' ||
                           C1.cap || ' Category1 ID: ' || v_category_id);
   
      insert into FA_CATEGORIES_TL
        (category_id,
         language,
         source_lang,
         last_update_date,
         last_updated_by,
         created_by,
         creation_date,
         last_update_login)
      values
        (v_category_id, 'US', 'US', sysdate, 1763, 1763, sysdate, 982535);
      insert into FA_CATEGORIES_TL
        (category_id,
         language,
         source_lang,
         last_update_date,
         last_updated_by,
         created_by,
         creation_date,
         last_update_login)
      values
        (v_category_id, 'ZHS', 'US', sysdate, 1763, 1763, sysdate, 982535);
   
      insert into FA_CATEGORIES_B
        (category_id,
         summary_flag,
         enabled_flag,
         owned_leased,
         last_update_date,
         last_updated_by,
         category_type,
         capitalize_flag,
         segment1,
         segment2,
         segment3,
         segment4,
         inventorial,
         created_by,
         creation_date,
         last_update_login)
      values
        (v_category_id,
         'N',
         'Y',
         'OWNED',
         SYSDATE,
         1763,
         'NON-LEASE',
         'YES',
         upper(C1.major),
         upper(C1.minor),
         upper(C1.sub),
         upper(C1.cap),
         'YES',
         1763,
         SYSDATE,
         982535);
   
      insert into FA_CATEGORY_BOOKS
        (category_id,
         book_type_code,
         last_update_date,
         last_updated_by,
         created_by,
         creation_date,
         last_update_login,
         asset_clearing_acct,
         asset_cost_acct,
         cip_clearing_acct,
         cip_cost_acct,
         deprn_expense_acct,
         deprn_reserve_acct,
         asset_cost_account_ccid,----
         asset_clearing_account_ccid,
         wip_cost_account_ccid,
         wip_clearing_account_ccid,
         reserve_account_ccid,
         bonus_deprn_expense_acct,
         bonus_deprn_reserve_acct,
         bonus_reserve_acct_ccid)
      values
        (v_category_id,
         C1.book_name,
         sysdate,
         1763,
         1763,
         sysdate,
         982535,
         C1.clear_account,
         C1.cost_account,
         C1.cip_clear_account,
         C1.cip_cost_account,
         C1.expense_account,
         C1.accumulated_deprn,
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.cost_account_cob),
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.clear_account_cob),
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.cip_cost_account_cob),
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.cip_clear_account_cob),
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.accumulated_deprn_cob),
         C1.expense_account,
         C1.accumulated_deprn,
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.accumulated_deprn_cob));
   
      insert into FA_CATEGORY_BOOK_DEFAULTS
        (category_id,
         book_type_code,
         start_dpis,
         life_in_months,
         deprn_method,
         prorate_convention_code,
         itc_eligible_flag,
         use_itc_ceilings_flag,
         depreciate_flag,
         retirement_prorate_convention,
         use_stl_retirements_flag,
         last_update_date,
         last_updated_by,
         created_by,
         creation_date,
         last_update_login,
         capital_gain_threshold,
         use_deprn_limits_flag,
         percent_salvage_value)
      values
        (v_category_id,
         C1.book_name,
         to_date('1970/01/01', 'YYYY/MM/DD'),
         C1.deprn_life * 12,
         C1.deprn_method,
         C1.deprn_proration,
         'NO',
         'NO',
         'YES',
         C1.retirement_proration,
         'NO',
         sysdate,
         1763,
         1763,
         sysdate,
         982535,
         12,
         'NO',
         C1.percent_salvage_value);
   
    elsif v_category_id is not null then
      dbms_output.put_line('v_category_id: ' || v_category_id);
      insert into FA_CATEGORY_BOOKS
        (category_id,
         book_type_code,
         last_update_date,
         last_updated_by,
         created_by,
         creation_date,
         last_update_login,
         asset_clearing_acct,
         asset_cost_acct,
         cip_clearing_acct,
         cip_cost_acct,
         deprn_expense_acct,
         deprn_reserve_acct,
         asset_cost_account_ccid,
         asset_clearing_account_ccid,
         wip_cost_account_ccid,
         wip_clearing_account_ccid,
         reserve_account_ccid,
         bonus_deprn_expense_acct,
         bonus_deprn_reserve_acct,
         bonus_reserve_acct_ccid)
      values
        (v_category_id,
         C1.book_name,
         sysdate,
         1763,
         1763,
         sysdate,
         982535,
         C1.clear_account,
         C1.cost_account,
         C1.cip_clear_account,
         C1.cip_cost_account,
         C1.expense_account,
         C1.accumulated_deprn,
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.cost_account_cob),
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.clear_account_cob),
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.cip_cost_account_cob),
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.cip_clear_account_cob),
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.accumulated_deprn_cob),
         C1.expense_account,
         C1.accumulated_deprn,
         (select CODE_COMBINATION_ID
            from gl_code_combinations_kfv
           where chart_of_accounts_id = '&Chart_Of_Account_ID'
             and concatenated_segments = C1.accumulated_deprn_cob));
   
      insert into FA_CATEGORY_BOOK_DEFAULTS
        (category_id,
         book_type_code,
         start_dpis,
         life_in_months,
         deprn_method,
         prorate_convention_code,
         itc_eligible_flag,
         use_itc_ceilings_flag,
         depreciate_flag,
         retirement_prorate_convention,
         use_stl_retirements_flag,
         last_update_date,
         last_updated_by,
         created_by,
         creation_date,
         last_update_login,
         capital_gain_threshold,
         use_deprn_limits_flag,
         percent_salvage_value)
      values
        (v_category_id,
         C1.book_name,
         to_date('1970/01/01', 'YYYY/MM/DD'),
         C1.deprn_life * 12,
         C1.deprn_method,
         C1.deprn_proration,
         'NO',
         'NO',
         'YES',
         C1.retirement_proration,
         'NO',
         sysdate,
         1763,
         1763,
         sysdate,
         982535,
         12,
         'NO',
         C1.percent_salvage_value);
 /*   dbms_output.put_line(''in);*/
    end if;
  end loop;
end;

<think>好的,我现在需要帮助用户解决如何在C#中为返回类型为IList<Dictionary<string, object>>的方法添加SQL分页逻辑的问题。首先,我需要理解用户的具体需求。用户提到他们想对现有方法进行分页处理,特别是针对返回这种复杂集合类型的方法。这可能涉及到数据库查询的优化,以减少数据传输量,提高性能。 首先,我应该回忆一下SQL分页的常见方法。通常,分页可以通过不同的SQL语法实现,比如在SQL Server中使用OFFSET FETCH,或者在MySQL中使用LIMIT和OFFSET。但用户使用的是C#,所以可能需要构建相应的SQL查询语句,并确保参数正确传递。 接下来,用户的方法返回类型是IList<Dictionary<string, object>>,这说明他们可能正在从数据库中读取动态结构的数据,每行数据以字典形式存储,键是列名,值是对象。这种情况下,可能需要保持灵活性,因为不同的查询可能有不同的列。 我需要考虑如何将分页参数(页码和每页数量)传递给SQL查询。通常,分页需要两个参数:页码(pageNumber)和每页的记录数(pageSize)。在SQL中,这通常转换为计算偏移量,即offset = (pageNumber - 1) * pageSize。然后,在查询中使用这个偏移量和pageSize来限制返回的结果。 例如,在SQL Server中,分页查询可能类似: SELECT * FROM TableName ORDER BY ColumnName OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY; 但用户可能需要动态构建这样的查询,尤其是当表名或排序字段不确定时。此外,参数化查询是必须的,以防止SQL注入攻击。 接下来,我需要考虑如何在C#代码中实现这一点。用户可能有一个现有的方法,比如从某个服务或仓储层获取数据,现在需要修改该方法以支持分页。例如,用户可能有一个类似的方法: public IList<Dictionary<string, object>> GetData() { // 原有逻辑,执行SQL查询并返回结果 } 现在需要将其改为支持分页,可能添加参数pageNumber和pageSize,并修改SQL语句。同时,还需要获取总记录数,以便客户端知道总页数。 因此,可能需要返回一个包含分页数据(即当前页的记录)和总记录数的对象。但用户的问题中返回类型是IList<Dictionary<string, object>>,所以可能需要调整返回类型,或者用户可能希望将总记录数通过其他方式返回,比如使用元组或自定义类。 不过,根据用户的问题,他们可能希望保持返回类型不变,只是分页后的数据。但通常分页需要返回总记录数,所以可能需要建议用户修改返回类型,或者提供另一个方法来获取总数。 现在,我需要考虑如何具体实现SQL分页。假设用户使用的是SQL Server,那么示例代码可能如下: public (IList<Dictionary<string, object>> Data, int TotalCount) GetPagedData(int pageNumber, int pageSize, string sortColumn = "Id") { int offset = (pageNumber - 1) * pageSize; string query = @" SELECT COUNT(*) FROM YourTable; SELECT * FROM YourTable ORDER BY @SortColumn OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY; "; using (var connection = new SqlConnection(connectionString)) { using (var command = new SqlCommand(query, connection)) { command.Parameters.AddWithValue("@SortColumn", sortColumn); command.Parameters.AddWithValue("@Offset", offset); command.Parameters.AddWithValue("@PageSize", pageSize); connection.Open(); using (var reader = command.ExecuteReader()) { // 读取总记录数 int totalCount = 0; if (reader.Read()) { totalCount = reader.GetInt32(0); } reader.NextResult(); // 读取分页数据 var data = new List<Dictionary<string, object>>(); while (reader.Read()) { var row = new Dictionary<string, object>(); for (int i = 0; i < reader.FieldCount; i++) { row[reader.GetName(i)] = reader.GetValue(i); } data.Add(row); } return (data, totalCount); } } } } 不过,这里有几个需要注意的地方: 1. 参数化查询中的排序字段(@SortColumn)可能无法直接使用参数,因为SQL参数不能用于列名或表名。这可能导致SQL注入风险,如果sortColumn来自用户输入。因此,可能需要验证sortColumn是否为有效的列名,比如白名单机制。 2. 返回类型可能需要调整,因为原来的方法返回IList<Dictionary<string, object>>,而分页通常需要返回数据和总记录数。所以用户可能需要创建一个包含这两者的对象。 3. 不同的数据库可能有不同的分页语法,比如MySQL使用LIMIT和OFFSET,而SQL Server 2012及以上使用OFFSET FETCH。需要确认用户使用的数据库类型。 此外,用户提到他们正在使用IList<Dictionary<string, object>>,这可能意味着他们从数据库中读取数据时使用了一些通用的方法,比如动态映射结果集到字典中,而不是使用具体的实体类。因此,在构建分页查询时,需要确保查询语句的正确性,特别是排序字段的正确处理。 另一个考虑点是性能。分页查询在大数据量时可能效率低下,尤其是当offset很大时。为了优化,可能需要使用更高效的分页方法,比如keyset分页(基于索引列的值进行分页,而不是OFFSET)。但用户的问题是关于SQL分页逻辑,因此可能暂时不需要涉及这个。 总结步骤: 1. 在方法中添加分页参数:pageNumber和pageSize,可能还有sortColumn。 2. 计算偏移量offset = (pageNumber - 1) * pageSize. 3. 构建SQL查询,包含获取总记录数的COUNT(*)和实际分页数据的两部分查询。 4. 执行查询,并处理结果,将数据部分转换为IList<Dictionary<string, object>>。 5. 返回数据和总记录数。 现在,需要确保示例代码正确,并处理可能的异常,比如参数验证(pageNumber至少为1,pageSize大于0),以及处理SQL注入风险,特别是动态排序字段的问题。 可能的解决方案中,针对排序字段,可以使用参数化查询,但需要知道参数化不能用于列名,所以必须对sortColumn进行验证,比如检查是否是有效的列名列表中的一员,或者转义处理。例如: var validColumns = new List<string> { "Id", "Name", "CreatedDate" }; if (!validColumns.Contains(sortColumn)) { throw new ArgumentException("Invalid sort column"); } 这样可以避免SQL注入。 此外,关于返回类型,用户可能需要调整方法返回类型以包含总记录数,但根据用户的问题,可能只需要分页后的数据,所以可能需要另一个方法来获取总数,或者修改现有方法。 另外,用户提到他们想对现有方法进行分页处理,所以可能需要在现有的数据访问层或服务层中进行修改,添加分页参数,并调整SQL查询。 最后,可能需要参考用户提供的引用内容。例如,引用[2]中提到了在接口中添加方法约定,比如Task<IEnumerable<Category>> ListAsync(),可能用户现在需要在这些方法中添加分页支持。因此,可能需要建议在接口中添加带有分页参数的方法,例如: Task<(IList<Dictionary<string, object>> Data, int TotalCount)> GetPagedDataAsync(int pageNumber, int pageSize, string sortColumn); 然后在实现中执行分页逻辑。 现在,整理这些思路,形成步骤化的回答,并确保代码示例正确,处理参数化查询、分页逻辑以及动态列的问题。</think>在C#中为返回类型为$IList<Dictionary<string, object>>$的方法添加SQL分页逻辑,需通过以下步骤实现: ### 一、分页实现步骤 1. **定义分页参数** 添加页码$pageNumber$和每页数量$pageSize$,计算偏移量: $$offset = (pageNumber - 1) \times pageSize$$ 2. **构建分页SQL语句** 使用数据库特定的分页语法(以SQL Server为例): ```sql SELECT * FROM TableName ORDER BY {SortColumn} OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY; ``` 3. **获取总记录数** 添加COUNT查询以支持前端分页控件: ```sql SELECT COUNT(*) FROM TableName; ``` 4. **参数化查询与动态列验证** - 对排序字段进行白名单验证防止SQL注入 - 使用参数化查询传递分页参数 ### 二、代码示例 ```csharp public (IList<Dictionary<string, object>> Data, int TotalCount) GetPagedData( int pageNumber, int pageSize, string sortColumn = "Id") { // 参数验证 if (pageNumber < 1) throw new ArgumentException("页码最小为1"); if (pageSize < 1) throw new ArgumentException("每页数量最小为1"); // 验证合法列名(示例列) var validColumns = new[] { "Id", "Name", "CreatedDate" }; if (!validColumns.Contains(sortColumn)) throw new ArgumentException("无效的排序字段"); int offset = (pageNumber - 1) * pageSize; // 构建SQL string query = $@" SELECT COUNT(*) FROM YourTable; SELECT * FROM YourTable ORDER BY [{sortColumn}] OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY; "; using var connection = new SqlConnection(_connectionString); using var command = new SqlCommand(query, connection); // 添加参数 command.Parameters.AddWithValue("@Offset", offset); command.Parameters.AddWithValue("@PageSize", pageSize); connection.Open(); using var reader = command.ExecuteReader(); // 读取总记录数 int totalCount = 0; if (reader.Read()) totalCount = reader.GetInt32(0); // 读取分页数据 reader.NextResult(); var data = new List<Dictionary<string, object>>(); while (reader.Read()) { var row = new Dictionary<string, object>(); for (int i = 0; i < reader.FieldCount; i++) { row[reader.GetName(i)] = reader.GetValue(i); } data.Add(row); } return (data, totalCount); } ``` ### 三、关键注意点 1. **性能优化** - 对排序字段建立索引可显著提升分页性能 - 大数据量时考虑`keyset分页`替代`OFFSET`[^1] 2. **接口适配** 若需在仓储层接口添加方法,可参考引用[2]的模式扩展: ```csharp public interface IYourRepository { Task<(IList<Dictionary<string, object>> Data, int TotalCount)> GetPagedDataAsync(int pageNumber, int pageSize, string sortColumn); } ``` 3. **空值处理** 注意字典中可能包含$null$值,需通过$DBNull.Value$转换处理[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值